浅解惰性函数链式调用

函数链

这里写一下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

你可能感兴趣的:(浅解惰性函数链式调用)