没有"每个"的jQuery性能差异

Ben*_*n J 9 jquery

更新已添加的jsfiddle - 请参阅帖子的底部

我目前有一个功能可以重新启用屏幕上所有禁用的字段.虽然它运行得非常快(根据Firebug profiler <1ms),我正在整理屏幕中的所有Javascript,并认为这个特殊功能似乎有点多余:

function enableDisabledFields() {
    $('[disabled]').each(function(i) {
        $(this).removeAttr('disabled');
    });
}
Run Code Online (Sandbox Code Playgroud)

我的印象是这3行可以替换如下,我预计如果不比至少相同的性能更好.

function enableDisabledFields() {
    $('[disabled]').removeAttr('disabled');
}
Run Code Online (Sandbox Code Playgroud)

显然我错了.第一个表现要好得多,我不太明白为什么.即使添加额外的选择器,例如:输入也没有区别(实际上会使情况变得更糟).

任何人都可以解决我的困惑吗?谢谢.

编辑我应该补充说我们正在使用旧版本的jQuery - 1.3.1我相信.

Edit2这里有一些jsFiddle链接.请记住,我可能误解了Firebug的剖析器(我认为似乎是这种情况).

选项1:http://jsfiddle.net/kcut7/

选项2:http://jsfiddle.net/ZgZpU/

Orb*_*ing 4

在 jQuery 1.3.1 中,其实现方式与当前版本略有不同:

v1.4.4

removeAttr: function( name, fn ) {
    return this.each(function(){
        jQuery.attr( this, name, "" );
        if ( this.nodeType === 1 ) {
            this.removeAttribute( name );
        }
    });
},
Run Code Online (Sandbox Code Playgroud)

v1.3.1

jQuery.each({
    removeAttr: function( name ) {
        jQuery.attr( this, name, "" );
        if (this.nodeType == 1)
            this.removeAttribute( name );
    }
}, function(name, fn){
    jQuery.fn[ name ] = function(){
        return this.each( fn, arguments );
    };
});
Run Code Online (Sandbox Code Playgroud)

功能或多或少相同,都.each()在所有情况下都用于处理列表。每个的定义根本没有改变:

// args is for internal usage only
each: function( object, callback, args ) {
    var name, i = 0,
        length = object.length,
        isObj = length === undefined || jQuery.isFunction(object);

    if ( args ) {
        if ( isObj ) {
            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 ( isObj ) {
            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;
},
Run Code Online (Sandbox Code Playgroud)

所以只是一个循环使用了.call()很多。

我认为关于通过额外的外循环提高速度的唯一解释.each()是数据结构大小在通过多层调用传递之前被大大减少到单个元素,这可能是在每个级别创建本地数据副本。传递整个列表来处理可能会产生更多的开销,需要分析堆的使用情况才能知道。