$.each(["a","b","c","d"],function(index , value){
console.log(index + ":" + value )
});
$("li").each(function (index) {
console.log(index + ":" + $(this).text());
})
这里我们看到jQuery.fn.each()的源码:
each: function( callback, args ) {
return jQuery.each( this, callback, args );
}
随后是jQuery.each()后面的代码,它处理了两种遍历对象:
each: function( obj, callback, args ) {
var value,
i = 0,
length = obj.length,
isArray = isArraylike( obj );
if ( args ) {
if ( isArray ) {
for ( ; i < length; i++ ) {
value = callback.apply( obj[ i ], args );
if ( value === false ) {
break;
}
}
} else {
for ( i in obj ) {
value = callback.apply( obj[ i ], args );
if ( value === false ) {
break;
}
}
}
// A special, fast, case for the most common use of each
} else {
if ( isArray ) {
for ( ; i < length; i++ ) {
value = callback.call( obj[ i ], i, obj[ i ] );
if ( value === false ) {
break;
}
}
} else {
for ( i in obj ) {
value = callback.call( obj[ i ], i, obj[ i ] );
if ( value === false ) {
break;
}
}
}
}
return obj;
}
延迟初始化是一种设计模式,它能延迟昂贵的过程,直到第一个实例需要时。其中一个示例就是jQuery中的ready()函数,当DOM准备就绪时,它仅执行一次回调。
实例ready方法
jQuery.fn.ready = function( fn ) {
// Add the callback
jQuery.ready.promise().done( fn );
return this;
};
实际实现
ready: function( wait ) {
// Abort if there are pending holds or we're already ready if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { return; } // Remember that the DOM is ready jQuery.isReady = true; // If a normal DOM Ready event fired, decrement, and wait if need be if ( wait !== true && --jQuery.readyWait > 0 ) { return; } // If there are functions bound, to execute readyList.resolveWith( document, [ jQuery ] ); // Trigger any bound ready events if ( jQuery.fn.triggerHandler ) { jQuery( document ).triggerHandler( "ready" ); jQuery( document ).off( "ready" ); } }
我们有时候需要控制对象的访问权限和上下文,这就是Proxy模式有用的地方。
当一个昂贵的对象应被实例化的时,Proxy模式可以帮助我们对其进行控制,提供高级的方法来引用对象,或修改对象,让它在特定的上下文中以一种特殊方式发挥作用。
在jQuery核心中,存在jQuery.proxy()方法,它接受函数作为参数,并返回一个始终具有特定上下文的新对象。这确保函数中的this值是我们所需要的值。
在下面的示例中它就很有用,在click事件处理程序内使用计时器时延迟执行。
$("button").on("click", function () {
setTimeout(function () {
$(this).addClass("active"); //this指向window
},100)
})
为了解决这个问题,我们可以使用jQuery.proxy()来实现代理模式类型。通过使用我们希望赋给this的函数和值来调用它,它实际上会返回一个函数,它会在正确的上下文保留该值。
$("button").on("click", function () {
setTimeout($.proxy(function(){
console.log(this.value);
},this),100);
})
jQuery源码中的实现:
proxy: function( fn, context ) {
var tmp, args, proxy;
if ( typeof context === "string" ) {
tmp = fn[ context ];
context = fn;
fn = tmp;
}
// Quick check to determine if target is callable, in the spec
// this throws a TypeError, but we will just return undefined.
if ( !jQuery.isFunction( fn ) ) {
return undefined;
}
// Simulated bind
args = slice.call( arguments, 2 );
proxy = function() {
return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
};
// Set the guid of unique handler to the same of original handler, so it can be removed
proxy.guid = fn.guid = fn.guid || jQuery.guid++;
return proxy;
}