下划线链接内部工作

时间:2013-10-15 09:26:49

标签: javascript closures underscore.js

我很好,_.chain function is implemented以及如何(或更好,为什么)它的工作原理。

特别是我的问题是每个函数的包装在哪里发生。让我们假设我正在使用_.chain(someArray).filter(...);当我进入函数时,我可以看到过滤器函数已转换为类似

的内容
function () { 
     var args = [this._wrapped]; //the data from chain(...)
     push.apply(args, arguments); //push to the (?) array
     return result.call(this, func.apply(_, args)); //?? where are these coming from?
}

我可以看到该函数在其范围内有3个闭包(将其与显示函数定义的un-chained function进行比较,而没有对它的原始函数进行全部闭包)

scope after using the chain function

第一个是find function本身,第二个是"the safe reference to the object itself",第三个是下划线类本身。

调用_.chain()时,转换的方式和位置(代码方式)(创建范围等)。我可以看到

//http://underscorejs.org/docs/underscore.html#section-139
 _.chain = function(obj) {
    return _(obj).chain();
  };

被调用,这将转到

//http://underscorejs.org/docs/underscore.html#section-145
//...
 chain: function() {
      this._chain = true;
      return this;
    },
//...

然后我被卡住了。我无法弄清楚从那里发生了什么。我假设魔法发生在constructor内,但我似乎无法弄清楚闭包的额外创建在哪里。所有的功能本身都没有显示被包裹的任何迹象,链调用看起来不像它包装的东西。 result似乎在那里,但我不知道它来自哪里。那么,这种情况发生在何处以及如何发生?

1 个答案:

答案 0 :(得分:0)

_.chain(obj)返回属性为_的{​​{1}}的新实例,_chain = true的实例将_属性设置为当前对象(这里工作很棒) 。第_wrapped行中的_.mixin(_)将所有下划线方法添加到下划线(构造函数)。 #1210方法替换并扩展_.mixin方法(仍具有父函数!可通过_访问)。 _.prototype更改了_.mixin实例的功能(这是您看到新功能的地方)。

新功能是:

_

(无论它是什么方法,对所有方法都一样,func参考原始方法)

function () { var args = [this._wrapped]; push.apply(args, arguments); return result.call(this, func.apply(_, args)); } 方法函数是:

result

因此,如果var result = function(obj) { return this._chain ? _(obj).chain() : obj; }; 返回的对象func.apply(_, args)_chain设置该属性)返回_.chain,那么您可以再次使用它:)

这是链接的过程但是原型呢!

在构造函数中:

_(obj).chain()

考虑一下:

var _ = function(obj) {
  if (obj instanceof _) return obj;
  if (!(this instanceof _)) return new _(obj); // This line do the magic
  this._wrapped = obj;
};

如果您想了解有关下划线mixin功能的更多信息,请阅读此内容(Underscore docs about OOP

我错过了什么吗?