实现链式调用实现 add函数,add(1)(2)(3)(4)输出10,然后考虑拓展性
// 解析为add(1)返回函数A,A(2)返回函数B, B(3)返回函数C
function add(num) {
var sum = 0;
sum += num;
return function(a) {
sum += a;
return functin(b) {
sum += b;
return function(c) {
sum += c;
return sum;
}
}
}
}
但是如果链式调用加长,这种方法显然不能满足需求
// 改进
function add(num) {
var sum = 0;
sum += num;
var func = function(param) {
sum += param;
return func;
}
return func;
}
// 这样调用的结果返回的是一个函数的字符串表示,那么怎样将结果输出呢?
js中对象到原始值的转换有两种方法
当一个对象转为原始值时,先查看对象是否有valueOf方法,如果有且返回值为一个原始值,则直接返回该原始值,否则调用toString方法,返回字符串表示
// 输出数字类型的结果
function add(num) {
var sum = 0;
sum += num;
var func = function(a) {
sum += a;
return func;
}
func.valueOf = function() { // 函数结果输出
return sum;
}
func.toString = function() {
return sum;
}
return func;
}
函数链式调用
实现函数的链式调用:util.chain(1).add(2).sum(3);
class utils {
chain(a) {
this.val = a;
return this;
}
sum(b) {
this.val += b;
return this;
}
sub(c) {
this.val -= c;
return this;
}
value() {
return this.val;
}
}
var util = new utils();
实现lazyman
// lazyMan类的封装
function _LazyMan(name) {
this.taskList = []; // 顺序执行队列
var self = this;
var fn = (function(n){
var name = name;
return function() {
console.log('Hi! This is ' + name + '!');
self.next();
}
})(name);
this.taskList.push(fn);
setTimeout(function(){
self.next();
}, 0); // 延迟执行函数
}
_LazyMan.prototype.next = function() {
var fn = this.taskList.shift(); // 获取第一个函数执行
fn && fn();
}
_LazyMan.prototype.eat = function(name) {
var self = this;
var fn = (function(n){
return function() {
console.log('Eat ' + name + '~');
self.next(); // 链式调用,启动下一个函数的执行
}
})(name);
this.taskList.push(fn);
return this; // 实现链式调用
}
_LazyMan.prototype.sleep = function(time) {
var self = this;
var fn = (function(time){
return function() {
setTimeout(function() {
console.log('Wake up after ' + time + 's!');
self.next();
}, time * 1000);
})(time);
this.taskList.push(fn);
return this;
}
_LazyMan.prototype.sleepFirst = function(time) {
var self = this;
var fn = (function(time){
return function() {
setTimeout(function() {
console.log('Wake up after ' + time + 's!');
self.next();
}, time * 1000);
})(time);
this.taskList.unshift(fn);
return this;
}
// 最后的封装
function LazyMan(name) {
return new _LazyMan(name);
}