`_.forEach`和`$.each`的区别

20
这两个函数_.forEach$.each 分别来自于 underscorejQuery ,它们似乎做相同的事情。
有什么可能的原因更喜欢其中一个实现而不是另一个?

1
我不会仅仅依赖于一个方法来决定选择哪个框架。 - Christoph
1
下划线不是一个框架。 - Kos
2
使用下划线版本,它遵循标准。 - I Hate Lazy
3个回答

17

_.forEach$.each 在传递给回调函数的参数上有所不同。

如果您使用 _.forEach,传递给回调函数的第一个参数是该值,而非键。
因此,如果您完全不关心键,则应使用 _.forEach

其他区别:

  1. _.forEach 更快一些,因为它在现代浏览器中使用原生的 Arrray.prototype.forEach
  2. this 的值也不同。jQuery 的行为不遵循标准,underscore 的行为则遵循。

1
jQuery如果可用,不使用本地的foreach循环吗?谢谢,我不知道这一点。 - Moritz Roessler
1
this 值也不同。jQuery 的行为不遵循标准,underscore 则遵循。而且 underscore 允许你使用第三个参数来设置 this 值。 - I Hate Lazy

6

它们主要提供了一个替代在IE8中不可用的forEach函数。

如果您正在迭代数组,则它们并不会添加太多东西。

除了回调参数的顺序之外,主要区别在于在jQuery中,该值也可以作为回调调用的上下文而可用(这就是为什么该值较不重要,只有提供第二个参数的原因)。除非您真的想避免向函数传递参数,否则这并不是优选它的主要原因:

var product = 1;
$.each([1, 2, 3], function(){ product *= this });

通常情况下,您不会同时使用这两个库,因此您只需使用您所拥有的库提供的迭代函数即可。
如果您不小心导入了这两个库,我建议使用underscore函数,因为:
  • 它最接近标准的ECMAScript数组函数,因此在IE8被淘汰后,您更容易进行迁移
  • 它更有效率,因为它会在本地函数可用时使用本地函数:
  • 查看源代码
    ...
    if (nativeForEach && obj.forEach === nativeForEach) {
         obj.forEach(iterator, context);
    ...
    

    2
    Underscore也接受普通对象而不是数组。http://jsfiddle.net/zdF6D/ jQuery的功能集较少,因为它不允许您通过第三个参数设置回调函数的“this”值。 - I Hate Lazy
    @IHateLazy 你说得对。我读源代码的速度太快了... - Denys Séguret
    我真的希望jQuery可以交换它的参数。我可以忍受不能设置回调函数的this值,但是参数位置颠倒让我有点疯狂。 - I Hate Lazy
    事实上,这很令人困惑。我同意这一点。而且,由于它可能被装箱,你不能总是使用它,这就禁止了你简单地总是使用它。 - Denys Séguret

    6

    jQuery的样子是这样的:

    something.each( function(index, Element) )
    

    Underscore的外观如下:

    _.each(list, function(Element, index, list), [context])
    // or
    _(list).each(function(Element, index, list), [context])
    

    原生数组.forEach 的语法如下:

    array.forEach(function(Element, index, list), [context])
    

    所以:

    • Underscore保持与本地forEach相同的参数顺序
    • JQuery和Underscore的实现有两个差异:
      • JQuery将this设置为Element,而本地和Underscore允许您提供自己的上下文
      • 本地和Underscore还将列表本身作为回调的第三个参数提供。

    编辑:为什么能够设置上下文很有用?

    考虑一下您有某种对象的情况:

    var worker = new FooWorker();
    worker.process(something);
    worker.process(somethingElse);
    

    假设你想要对数组中的每个值都调用该方法。
    通过使用上下文参数,你可以简单地这样说:

    myArray.forEach(worker.process, worker);
    

    如果没有它,您需要更冗长的代码(并且每个元素都需要调用一个额外的函数):

    // native
    myArray.forEach( function(i, e) {worker.process(e);} );
    // jquery
    $(myArray).each( function() {worker.process(this); } );
    

    这是一个情况,其中JQuery的foreach惯例使事情变得不那么方便。

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接