更新已添加的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的剖析器(我认为似乎是这种情况).
在 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()是数据结构大小在通过多层调用传递之前被大大减少到单个元素,这可能是在每个级别创建本地数据副本。传递整个列表来处理可能会产生更多的开销,需要分析堆的使用情况才能知道。