21

有谁为什么其他优秀的jQuery.each功能与(现在)原生的设计不同Array.forEach?前:

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(可能还有其他库)以相反的方式(更类似于本机函数)。

4

3 回答 3

15

好吧,我想我们必须向雷西格先生本人寻求解释。事实上,在设计和开发 jQuery 时,ECMAscript 262 第 5 版并不是很普及,所以这肯定会发挥作用。而且由于它是这样设计的,他们不想在以后更改它并破坏所有现有代码。

实际上,您更可能希望访问具有更高优先级的元素,而不是在循环Array时访问它的索引。所以,对我来说,没有合理的解释为什么你会首先将索引传递给回调。

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

另一方面,如果它给您带来太多困扰,您可以简单地创建一个快捷方式并使用本机Array.prototype.forEach来迭代您的 jQuery 包装集:

var forEach = Function.prototype.call.bind( Array.prototype.forEach );

forEach( $('div'), function( node ) {
    console.log( node );
});

..对于标准Arrays,只需使用其原生原型即可。

在实现条件返回假/真时,我们必须知道哪个部分以哪种方式工作。当您在 Array.prototype.forEach 中使用带有条件的 return false 时,它​​被视为继续,但是当您使用 return false 时,在 $.each 中带有条件时,它被视为 break 语句。

var listArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
var arr1 =[];var arr2=[];
var rv = true;
listArray.forEach(function(i, item) {
  if (i == 5) {
    return rv = false;
  }
 arr1.push(i)
  return rv;
});
var listArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
jQuery.each(listArray, function(i, item) {
  if (item == 5) {
    return rv = false;
  }
  arr2.push(i)
});
  console.log("forEach=>"+arr1)
  console.log("$.each=>"+arr2)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

于 2012-10-26T23:16:06.183 回答
6

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

所以本质上,答案是他们做出了一个错误的决定(Resig 是一个令人难以置信的程序员,但即使他也不完美)现在每个使用 jQuery 的人都必须在剩下的时间里受苦,因为该库在新版本(让我们面对现实吧,这是一件好事:您不希望每次升级 jQuery 时都必须重新编写整个站点)。

还值得一提的是,Underscore 库确实有一个each与内置的签名相同的方法each。事实上,Underscore 的版本实际上使用了内置版本(如果存在),为了获得更好的性能,如果浏览器不支持内置的each. 由于 jQuery 对象只是数组,您可以轻松地将它们与_.each.

于 2012-10-26T23:26:34.630 回答
1

好吧,我同意使用key第二个更有意义,但是您必须记住$.each,可以与对象或数组一起使用,对于对象,您可能需要键,因为它们有意义。

于 2012-10-26T23:26:45.880 回答