我应该使用 jQuery.each() 吗?

Posted

技术标签:

【中文标题】我应该使用 jQuery.each() 吗?【英文标题】:Should I use jQuery.each()? 【发布时间】:2010-12-25 09:53:44 【问题描述】:

我对对象数组进行了非常频繁的迭代,并且一直在使用 jQuery.each()。但是,我遇到了速度和内存问题,根据我的分析器,最常调用的方法之一是 jQuery.each()。街上对它的表现有什么看法?我应该切换到简单的 for 循环吗?当然,我也在自己的代码中修复了许多问题。

【问题讨论】:

请记住关于分析器,许多内置的 jQuery 操作也在内部使用 $.each() 来执行它们的工作。 您的问题是关于 jQuery.each() 还是 jQuery().each() ? .. 第一种形式(你问的) - 相当于一个简单的 for 循环。 【参考方案1】:

This article (#3) 运行了一些性能测试,发现 jQuery .each 函数的速度大约是原生 javascript for 循环的 10 倍。

来自10 Ways to Instantly Increase Your jQuery Performance - 3. Use For Instead of Each使用Firebug,可以测量这两个函数的运行时间。

var array = new Array ();
for (var i=0; i<10000; i++) 
    array[i] = 0;


console.time('native');
var l = array.length;
for (var i=0;i<l; i++) 
    array[i] = i;

console.timeEnd('native');

console.time('jquery');
$.each (array, function (i) 
    array[i] = i;
);
console.timeEnd('jquery');

以上结果对于原生代码是 2ms,对于 jQuery 的“each”方法是 26ms。如果我在本地机器上对其进行了测试,并且它们实际上并没有做任何事情(只是一个数组填充操作),jQuery 的每个函数所占用的时间是 JS 原生“for”循环的 10 倍以上。当处理更复杂的事情时,这肯定会增加,比如设置 CSS 属性或其他 DOM 操作操作。

【讨论】:

这应该是答案。只是因为each,我的动态分页不稳定。此外,链接提供了很好的建议。刚刚注意到我只做了大约 40% 虽然这个答案已有一年多的历史并且该链接很有帮助,但如果您将答案的基本部分发布在此网站上会更好,否则您的帖子可能会被删除See the FAQ where it mentions answers that are 'barely more than a link'.您如果您愿意,仍然可以包含该链接,但仅作为“参考”。答案应该是独立的,不需要链接。 @bluefeet 这个答案已经有将近 5 年的历史了。让我休息一下。我也确实包含了链接的重要部分。 “发现 jQuery .each 函数的速度大约是原生 javascript for 循环的 10 倍。”没有比这更重要的了。 @JaceRhea 我评论的唯一原因是这被标记为低质量并被要求将其删除。我想我会给你一个机会首先改进它的“仅链接”性质。【参考方案2】:

jQuery 的源代码如下(感谢 John Resig 和 MIT License):

each: function( object, callback, args ) 
    var name, i = 0, length = object.length;

    if ( args ) 
        if ( length === undefined ) 
            for ( name in object )
                if ( callback.apply( object[ name ], args ) === false )
                    break;
         else
            for ( ; i < length; )
                if ( callback.apply( object[ i++ ], args ) === false )
                    break;

    // A special, fast, case for the most common use of each
     else 
        if ( length === undefined ) 
            for ( name in object )
                if ( callback.call( object[ name ], name, object[ name ] ) === false )
                    break;
         else
            for ( var value = object[0];
                i < length && callback.call( value, i, value ) !== false; value = object[++i] )
    

    return object;

如您所见,在大多数情况下,它使用的是基本的 for 循环,其中唯一的开销实际上就是回调本身。应该不会影响性能。

编辑:这是因为选择器开销已经发生,并且您得到了一个填充数组object

【讨论】:

当然。和我们大多数人一样,遗憾的是。但你的具体观点是什么?我的观点是“每个”的核心只是一个 for 循环。我留下了实例化 jQuery 对象和单独选择 dom 元素所带来的开销。 我的意思是不要低估函数调用的开销。 目前,JS 中的函数调用实际上相当慢。正在努力。 点得好。谢谢大家。 我对这些回调有多慢感到惊讶:jsperf.com/jquery-each-vs-for-loop/31【参考方案3】:

这种方法应该会给您带来显着的速度提升。

var elements = $('.myLinks').get(), element = null;
for (var i = 0, length = elements.length; i < length; i++) 
    element = elements[i];
    element.title = "My New Title!";
    element.style.color = "red";

缓存也会提高性能。

function MyLinkCache() 
    var internalCache = $('.myLinks').get();

    this.getCache = function() 
        return internalCache;  
    

    this.rebuild = function() 
        internalCache = $('.myLinks').get();
    

使用中:

var myLinks = new MyLinkCache();

function addMyLink() 
    // Add a new link.
    myLinks.rebuild();


function processMyLinks() 
    var elements = myLinks.getCache(), element = null;
    for (var i = 0, length = elements.length; i < length; i++) 
        element = elements[i];
        element.title = "My New Title!";
        element.style.color = "red";
    

【讨论】:

【参考方案4】:

确保充分利用 jquery 的一种方法是将返回的结果数组存储在一个变量中,而不是每次需要获取某些东西时都重新遍历 DOM。

不该做的例子:

$('.myLinks').each(function()
    // your code here
);
$('.myLinks').each(function()
    // some more code here
);

更好的做法:

var myLinks = $('.myLinks');
myLinks.each(function()
    // your code here
);
myLinks.each(function()
    // some more code here
);

【讨论】:

更好的做法:在一个循环中完成所有操作。 如果运行一次,两个示例肯定是相同的吗?在 jQuery 遍历对象之前,它会设置一个变量,就像您在第二个示例中所做的那样。如果您必须多次运行.each 语句,那么缓存变量可能会有所帮助。【参考方案5】:

使用本机功能通常会更快 比抽象,例如 JQuery.each() 方法。但是,JQuery.each() 方法更容易使用,并且需要更少的编码。

说实话,没有任何背景,任何一个都不是正确或错误的选择。我认为我们应该首先编写更简单的代码,假设它是好的/易读的/干净的代码。如果您遇到一种情况,例如您所描述的情况,存在明显的滞后,那么是时候找出瓶颈所在并编写更快的代码了。

在这些场景中替换 JQuery.each() 方法可能会有所帮助,但是,在没有看到您的代码的情况下,您可能遇到与 JQuery 方法无关的瓶颈。

【讨论】:

以上是关于我应该使用 jQuery.each() 吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 jQuery.each 中附加元素时出现错误

jquery $.each()循环退出

jQuery 每个总是排序吗?

在 Javascript 文件中使用 jQuery.each() 时,下拉列表中未填充数组中的数据

如何,使用 JQUERY .EACH() 但不用于元素,用于变量

如何使用 jquery each() 方法在数组中追加多个对象