我很好,_.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进行比较,而没有对它的原始函数进行全部闭包)
第一个是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
似乎在那里,但我不知道它来自哪里。那么,这种情况发生在何处以及如何发生?
答案 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)
我错过了什么吗?