我們都用過Jqurey中的each函數,都知道each()有兩種方式去調用,一種是透過$.each()調用,另一種是$(selector).each()去調用,那麼它們之間有什麼區別?
翻看一下Jquery原始碼就會知道,$.each()是核心的實現,$(selector).each()是呼叫的$.each(),先來分析一下$.each( )的原始碼(在底部):
each(obj,callback,args)函數接收3個參數:obj--要遍歷的物件或陣列、callback--要遍歷執行的回呼函數、args--自己指定的陣列(先無視)。
jQuery中each方法的實作使用call方法,call方法可以設定上下文,第一,在下例中數組each效果一樣,為什麼不直接呼叫呢?
透過call 可以改變this的指向。
var testCall = function(obj, callback){ callback.call(obj, 1); }
testCall(["一、改變this的指向", "二、函數內部可以透過this調用"], function(index){ //使用call方式調用,可以直接透過this存取call 的第一個參數傳入的物件。 this。
var test = function(obj, callback){ callback(obj, 1); }
#jQuery.each 應該就是用call 修改的this 指向;
$.each([1,2,3], function (index, item) { console.log({index:index,value:item,_this:this}); });/* Object {index: 0, value: 1, _this: Number} Object {index: 1, value: 2, _this: Number} Object {index: 2, value: 3, _this: Number} */
var each = function(arr, callback){ for( var index = 0 ; index < arr.length ; index++ ){ callback.call(arr[index], index, arr[index]); } } each([1,2,3], function (index, item) { console.log({index:index,value:item,_this:this}); });/* Object {index: 0, value: 1, _this: Number} Object {index: 1, value: 2, _this: Number} Object {index: 2, value: 3, _this: Number} */
注意:this,如果沒有 使用 call,在回呼函數中是沒辦法使用 this 的。
1.沒有args的情況
一般來說,args是不常用的,所以先不討論當if(args)成立的情況,也就是直接看在程式碼中標為灰色的部分,這也是each()函數核心的部分
if(isArray) { for(; i < length; i++) { value = callback.call(obj[i], i, obj[i]); if(value === false) { break; } } }
如果你要遍歷的對象,是數組類型,則進入此程式碼區塊
for循環
遍歷數組
的每個元素,然後利用call方法,執行obj[i].callback(i,obj[i]), 所以,自己再寫回調函數的時候,應該意識到jquery會用數組的每個物件去執行你的回呼函數,參數傳的是元素在陣列中index和該元素,同時回呼方法內部的this,也指向該元素; 下一行是判斷回呼函數是否傳回了值,如果回呼函數傳回false,則跳出該陣列的循環。 如果自己傳的物件也是可以遍歷的,程式碼和上面數組遍歷也是一樣的
else { for(i in obj) { value = callback.call(obj[i], i, obj[i]); if(value === false) { break; } } }
的屬性,
原理和上面一樣,只不過換成物件內部的屬性x,去執行回呼函數,相當於obj.attr.callback(i,obj.attr); 回掉函數中如果傳回false,也是會結束循環操作。 2.有args的情況
當呼叫each()有第三個參數的時候,就會進入下面的程式碼區塊,來分析下:
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; } } }
同樣道理,會先判斷你要遍歷的物件是否是數組,如果是數組,則遍歷數組的元素obj[i],並執行obj[i].callback(args)注意!這個地方傳的參數是你自己傳入的args數組,這是和沒有args參數不一樣的地方,也就是說如果你調用each函數是傳入了自己的數組參數,回調函數的參數
列表就是你所傳的args數組。其他的同上。
$(selector).each(callback,args)函數接收2個參數:callback--要遍歷執行的回呼函數、args--自己指定的陣列。明白了$.each()函數,$(selector).each就簡單了,翻開源碼,$(selector).each內部就是呼叫的$.each()函數,原始碼如下:each: function( callback, args ) {
return jQuery.each( this, callback, args );
},
可以看到,在呼叫$.each()的時候,obj參數是寫成了this,也就是$(selector),這是jquery選擇器回傳一個jquery
。
總結:$.each()和$(selector).each()的差別就是前者可以針對所有物件或陣列進行遍歷,而後者是針對jquery選擇器傳回的jquery內部物件進行遍歷,前者更強大一些
以上是Jquery的$(selector).each()和$.each()區別實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!