函数链
这里写一下lodash的函数链式调用
我曾经在哪里看过类似的源码,但又忘记了 现在来模拟一下
我们来看以下代码,实际上lodash这种函数调用,是在真正执行.value时,才会调用函数链上的方法
_.chain(persons)
.filter(s=> !_.isUndefined(s) && !_.isNull(s))
.map(_.property('address.country')) // 使用_.property抽取person对象的address.country属性,这是Ramda的R.viw()的Lodash对应版本
.reduce(gatherStats,{})
.values() // 这里将对象创建成了可枚举的数组对象
.sortBy('count')
.reverse()
.first()
.value()
我想起来了,是在es6的proxy里面写了相关东西
思考上述写法的难点在哪里?是当我.xxx时,要将这个函数存到一个队列中,在当执行.value时,才逐个调用函数链上的方法.
es5的做法,面向对象,通过原型链既可以模拟这一效果
function Chain(instance) {
if(this instanceof Chain) {
this.instance = instance
this.stack = []
} else {
return new Chain(instance)
}
}
Chain.prototype.value = function() {
let result = this.stack.pop()
while(result) {
result()
result = this.stack.pop()
}
return this.instance
}
const fnMap = {
filter : function(arr,fn) {
let temp = [],
length = arr.length,
index = -1
while(++index < length) {
if(fn(arr[index])) {
temp.push(arr[index])
}
}
return temp
},
map : function(arr,fn) {
let temp = [],
length = arr.length,
index = -1
while(++index < length) {
temp.push(fn(arr[index]))
}
return temp
}
}
Object.keys(fnMap).forEach(key=> {
console.log(key)
Chain.prototype[key] = function(fn) {
let self = this
this.stack.push(function() {
self.instance = fnMap[key](self.instance,fn)
})
return this
}
})
console.log(Chain([1,2,3]).map(item=>item * 6).filter(item=>item!==6).value()) // logs [6,12,18]
es6可以使用proxy做到可以点击这里看es6proxy
const pipe = function(value) {
const fnStack = [],
oproxy = new Proxy({},{
get : function(target,key) {
if(key === 'get') {
return fnStack.reduce(function (val, fn) {
return fn(val);
},value);
}
fnStack.push(window[key]);
return oproxy;
}
})
return oproxy;
}
var double = n => n * 2;
var pow = n => n * n;
var reverseInt = n => n.toString().split("").reverse().join("") | 0;
pipe(3).double.pow.reverseInt.get; // 63
网友评论