前言
上面一篇写了如何_(arr).unique(func)或者_.unique(arr, func)调用,这篇讲解如何真正的链式调用,类似arr.unique(func).map(mapf)
开启和结束链式调用
首先调用两个方法表示开始和结束链式调用,比如chain()开启链式调用,value()结束调用返回结果,类似
_(arr).chain().unique(func).map(mapf).value()
_.chain(arr).unique(func).map(mapf).value()
chain
_.chain = function (obj) {
let instance = _(obj); //通过之前的function 创建无new 化实例
instance._chain = true; //确认链式调用,用于后面判断是否链式调用
return instance;
};
result
因为不是每一次调用都是链式调用,所以需要判断是否是链式调用,如果是则将结果储存起来,如果不是,则返回结果
let result = function (instance, data) {
if (instance._chain) {
instance.warp = data; //将返回的结果存入warp中,用于后面的计算取值
return instance;
}
return data;
};
接下来需要改造mixin方法,使之适用于链式调用和非链式调用
_.mixin = function (obj) {
_.each(_.functions(obj), function (key) {
let func = obj[key];
_.prototype[key] = function () {
let args = [this.warp];
Array.prototype.push.apply(args, arguments);
return result(this, func.apply(this, args));
};
});
};
value
最后则是返回结果
//如果写成_.value 的话,最后结束链式调用的时候,还是会因为mixin而被认为是调用一个函数 最后return的还是result 中的instance
_.prototype.value = function () {
return this.warp;
};
完整代码
(function (root) {
var _ = function (obj) {
if (!(this instanceof _)) {
return new _(obj) //无 new 实例
}
this.warp = obj
}
let result = function (instance, data) {
//console.log(instance, data, 'result')
if (instance._chain) {
instance.warp = data
return instance
}
return data
}
_.chain = function (obj) {
//console.log(this, obj, 'chain')
let instance = _(obj) //通过上面的function 无new化实例
instance._chain = true //确定开始链式调用
return instance
}
_.prototype.value = function () {
//console.log(this, 'value')
return this.warp
}
_.map = function (arr, callback) {
return arr.map((item) => {
return callback ? callback(item) : item
})
}
//去重
_.unique = function (arr, callback) {
let result = []
for (let i = 0; i < arr.length; i++) {
let target = callback ? callback(arr[i]) : arr[i]
if (result.indexOf(target) === -1) {
result.push(target)
}
}
return result
}
_.max = function () { }
_.each = function (arr, callback) {
for (let i = 0; i < arr.length; i++) {
//console.log(arr[i])
callback(arr[i])
}
}
_.functions = function (obj) {
let arr = []
for (const key in obj) {
arr.push(key)
}
return arr
}
//_([123]).map(function(){})
_.mixin = function (obj) {
_.each(_.functions(obj), function (key) {
let func = obj[key]
_.prototype[key] = function () {
let args = [this.warp]
//数组合并
//let arr=[].slice.call(arguments)
//arr.forEach((item)=>{args.push(item)})
//Array.prototype.push.apply(args, [1,2,3])
Array.prototype.push.apply(args, arguments)//arguments 可以传递多个callback
//func.apply(this, args) //[数据,迭代器]
return result(this, func.apply(this, args))
}
})
}
_.mixin(_)
root._ = _
})(this)
好的,undersore的链式调用就结束了,如果有错误希望大佬指出,如果有更好的方法,也同样希望指教,谢谢。