美文网首页
Underscore源码阅读:链式调用

Underscore源码阅读:链式调用

作者: San十二 | 来源:发表于2018-11-16 13:49 被阅读0次

    chain

    _.chain(lyrics)
      .map(function(line) { return line.words.split(' '); })
      .flatten()
      .reduce(function(counts, word) {
        counts[word] = (counts[word] || 0) + 1;
        return counts;
      }, {})
      .value();
    

    Underscore支持链式调用;不过要求函数链的开头要用chain函数生成封装对象。
    看看chain到底做了啥。

      _.chain = function (obj) {
        var instance = _(obj);
        instance._chain = true;
        return instance;
      };
    

    chain生成了返回了一个underscore实例

      var _ = function (obj) {
        if (obj instanceof _) return obj;
        if (!(this instanceof _)) return new _(obj);
        this._wrapped = obj;
      };
    

    我们看到underscore实例就是一个挂载了_wrapper的对象。

    再接着,因为_是个构造函数,所有方法都是挂载在构造函数上的。
    Underscore提供了mixin方法为Underscore对象进行扩展,我们看看。

      _.mixin = function (obj) {
        _.each(_.functions(obj), function (name) {
          // 对传入的obj,遍历它所有的方法,先挂载在构造函数上
          var func = _[name] = obj[name];
          // 并且所有的方法都会在原型上重写;
          _.prototype[name] = function () {
            var args = [this._wrapped];
            push.apply(args, arguments);
            return result(this, func.apply(_, args));
          };
        });
      };
    
      _.mixin(_);
    

    Underscore通过mixin将原来挂载在构造函数上所有的方法,全部在_的原型上重写,这次重写,直接指定了underscore所有方法的第一个参数为this._wrapped,也就是构造函数携带的参数。

    然后看看最后为了链式调用返回的result函数。明显支持这种“不带”第一个参数的写法是只能写在underscore实例上的。所以在原型上重写的方法,最后返回的仍然是underscore实例。

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

    也就是说,underscore的链式调用一直返回的是一个_的实例,_的构造方法不仅挂载了全部underscore的方法,并且在原型上重写了这些方法,使得_的实例可以不用传递第一个参数而进行链式调用。

    相关文章

      网友评论

          本文标题:Underscore源码阅读:链式调用

          本文链接:https://www.haomeiwen.com/subject/caoufqtx.html