jQuery.each实现与本机Array.forEach不同

有没有人为什么是优秀的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 });​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ 

并不是让我感到困扰,我更喜欢使用原生的polyfills来获得最常见的新数组函数,但我一直对设计决策感到好奇。 也许它是在浏览器实现原生forEach并且传统支持阻止他们更改它之前的较旧时间制作的,或者……?

或者,也许是这样设计的,因为它也可以在本机对象上使用,而不是把关键值放在回调中的“有意义”……?

旁注:我知道underscore.js(也许还有其他库)反过来(更类似于原生函数)。

好吧,我想我们不得不问Resig先生自己对此有所解释。 事实上, ECMAscript 262第5版在jQuery设计和开发的时候并不是非常普遍,所以这肯定会发挥作用。 由于它是这样设计的,因此他们不想在以后更改它并破坏所有现有代码。

事实上,您更有可能要访问具有更高优先级的元素,而不是循环数组时的索引。 所以,对我来说没有合理的解释为什么你会先将索引传入回调。

请放心,如果今天发明了jQuery,它们将遵循本机实现行为。

另一方面,如果它太烦你了,你可以简单地创建一个快捷方式并使用原Array.prototype.forEach来迭代你的jQuery包装集:

 var forEach = Function.prototype.call.bind( Array.prototype.forEach ); forEach( $('div'), function( node ) { console.log( node ); }); 

..对于标准arrays ,只需使用他们的原生原型。

这实际上是在最后一个jQuery conf中提到的; 不幸的是我不记得细节了,但是如果你从中看到足够的video,我想你可以找到它(我认为这是在主题演讲之后的Q&A期间,但不要引用我的话)。 无论如何有人(我认为这不是Resig本人,而是另一位高级jQuery组织成员)基本上说“jQuery有一些我们都知道有问题的东西(”每个“都是他们给出的例子之一)但是有数百万的那里的网站现在依赖于那些有问题的行为,所以我们现在无法改变它。“

所以从本质上讲,答案是他们做出了一个错误的决定(Resig是一个令人难以置信的程序员,但即使他并不完美)现在每个人都使用jQuery必须忍受其余的时间,因为库保持相对较高的向后兼容性新版本(让我们面对它,这是一件好事:你不想每次升级jQuery时都要重写整个网站)。

还值得一提的是,Underscore库的each方法都具有与内置的each方法相同的签名。 事实上,Underscore的版本实际上使用内置版本(如果存在)以获得更好的性能,如果浏览器不支持内置版本,则仅依赖其版本。 由于jQuery对象只是数组,因此您可以轻松地将它们与_.each一起使用,并且由于_.each在jQuery中缺少许多其他function,因此它是一个很好的库来补充jQuery。

我同意将key第二个更有意义,但你必须记住$.each可以与对象或数组一起使用,在对象的情况下,你可能需要键,因为它们有意义。