Underscore.js 源码解读之链式语法

链式语法写法

我们调用多个 Underscore 的方法。可能会这么写:

var arr = [1, 2, 3,4,5,6,7,8]
var res = _.filter(arr, i => i > 1)
res = _.map(res, i => i*2)
res = _.shuffle(res)

用 Underscore 的链式语法来简化,如下

var arr = [1, 2, 3,4,5,6,7,8]
var res = _.chain(arr)
 .filter(i => i > 1)
 .map(i => i * 2)
 .shuffle()
 .value()

源码实现

链式语法本质是,每次调用方法,都返回 Underscore 实例(this)。

我们先来看 chain 的源码:

_.chain = function(obj) {
  var instance = _(obj) // 生成实例。
  instance._chain = true // 用此变量来标识:方法是返回原始值还是 Underscore 实例
  return instance;
}

在生成实例的过程中,会将值存起来。源码如下:

var _ = function(obj) {
  if (obj instanceof _) return obj;
  if (!(this instanceof _)) return new _(obj);
  this._wrapped = obj; // 将当前值存起来。
}

在 Underscore 用 mixin,将所有的静态方法绑并到实例方法。源码如下:

_.mixin = function(obj) {
  _.each(_.functions(obj), function(name) {
    var func = _[name] = obj[name];
    _.prototype[name] = function() {
      var args = [this._wrapped];
      push.apply(args, arguments);
      return result(this, func.apply(_, args));
    };
  });
};

// 将所有的静态方法绑并到实例方法
_.mixin(_)

上面有一句关键代码

return result(this, func.apply(_, args))

result 方法做的事就是在链式调用中,将实例传递下去。源码如下:

var result = function(instance, obj) {
  return instance._chain ? _(obj).chain() : obj;
}

获得最后结果的值,调用 value 方法。源码如下:

_.prototype.value = function() {
  return this._wrapped;
};

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 7,999评论 4 43
  • 忙比赛和培训事宜。从外地回来后,果然休息后神清气爽。。打满鸡血的我又要回来了。。今天赶紧借了点货,维护好我的大客户们。。
    Yao_3019阅读 81评论 0 0
  • 最近开始抄写掌控每一天流程图,同时自己也在看DOIT.IM这个软件怎么用,其中的“情境”标签不是太理解。几天前加...
    青苗妈2016阅读 289评论 6 4
  • 今天基本处于浑浑噩噩的状态,做什么都不来劲。 还在想着一个问题,客户给的信息太少,却还要找人时,该怎么处理。 这实...
    alaio阅读 183评论 4 0
  • 幸福像花儿一样 高中时代的恋情,简单纯粹,并不掺夹任何多余的因素。纯粹的喜欢,纯粹的去爱。也不会考虑任何在未来所有...
    天妒阅读 92评论 0 0
  • 雪花漫天地飘落, 风带着怒号, 它们用曼妙的身姿,强健的声音告诉你: 冬来了。 大雁南飞寻找温暖, 青蛙冬眠等待春...
    小蜗牛忧忧阅读 133评论 0 0