为什么其他优秀jQuery.each
函数的设计与(现在)原生Array.forEach
的设计不同? F.ex:
var arr = ['abc','def'];
arr.forEach(function(entry, index) {
console.log(entry); // abc / def
});
这绝对有道理。但是jQuery选择将index
作为第一个参数:
$.each(arr, function(index, entry) {
console.log(entry);
});
有谁知道这个设计决定背后的原因?我总是广泛地使用$.each
,但它始终告诉我索引是第一个参数,因为它很少使用。我知道jQuery通过this
实现了一个直接引用,但是如果你这样做的话会非常混乱:
var arr = ['abc','def'];
$.each(arr, function() {
console.log(this === 'abc'); // false both times, since this is a String constructor
});
并不是让我感到困扰,我更喜欢将原生的polyfill用于最常见的新数组函数,但我一直对设计决策感到好奇。也许它是在浏览器实现原生forEach
并且遗留支持阻止他们更改它之前的较旧时间制作的,或者......?
或许,它是以这种方式设计的,因为它也可以在本机对象上使用,而不是把键放在回调值之前“有意义”......?
旁注:我知道underscore.js(也许还有其他库)反过来(更类似于原生函数)。
答案 0 :(得分:14)
嗯,我想我们不得不问Resig先生自己对此有所解释。事实上, ECMAscript 262版本5 在jQuery设计和开发的时候并不是非常普遍,所以这肯定会发挥作用。由于它是这样设计的,因此他们不想在以后更改它并破坏所有现有代码。
事实上,在循环数组时,您更有可能要访问优先级高于其的索引。所以,对我来说,没有合理的解释为什么你首先将 index 传递给回调。
请放心,如果今天发明了jQuery,它们将遵循本机实现行为。
另一方面,如果它太烦你,你可以简单地创建一个快捷方式并使用原生的Array.prototype.forEach
来迭代你的jQuery包装集:
var forEach = Function.prototype.call.bind( Array.prototype.forEach );
forEach( $('div'), function( node ) {
console.log( node );
});
..对于标准 Arrays ,只需使用他们的原生原型。
答案 1 :(得分:6)
这实际上是在最后一个jQuery conf中提到的;不幸的是我不记得细节,但是如果你从中看到足够多的视频,我想你可以找到它(我认为它是在主题演讲之后的Q& A中,但是不引用我在那)。无论如何有人(我认为不是Resig本人,而是另一位高级jQuery组织成员)基本上说“jQuery有一些我们都知道有问题的东西(”每个“都是他们给出的例子之一)但是有数百万的那里的网站现在依赖于那些有问题的行为,所以我们现在无法改变它。“
所以从本质上讲,答案是他们做出了一个糟糕的决定(Resig是一个令人难以置信的程序员,但即使他并不完美)现在每个人都使用jQuery必须忍受其余的时间,因为库保持相对较高新版本的向后兼容性(让我们面对它,这是一件好事:你不想每次升级jQuery时都要重写整个网站。)
还值得一提的是,Underscore库 的each
方法具有与内置each
相同的签名。实际上,Underscore的版本实际上使用内置版本(如果存在)以获得更好的性能,如果浏览器不支持内置each
,则仅依赖其版本。由于jQuery对象只是数组,因此您可以轻松地将它们与_.each
一起使用,并且由于Underscore在jQuery中缺少许多其他功能,因此它是一个很好的库来补充jQuery。
答案 2 :(得分:1)
我同意让key
秒更有意义,但你必须记住$.each
可以与对象或数组一起使用,对于你可能需要的对象钥匙因为它们有意义。