2012-06-19 32 views
6

昨晚在閱讀jQuery Cookbook(Oreilly)時,我發現每個函數都會產生一個問題,我似乎無法在本書或在線中找到答案。 我用這個問題的代碼是從jQuery site發現,我把它下面作爲參考:

<script> 
    $(document.body).click(function() { 
     $("div").each(function (i) {   //Where does the 'i' come from? 
     if (this.style.color != "blue") { 
      this.style.color = "blue"; 
     } else { 
      this.style.color = ""; 
     } 
     }); 
    }); 
</script> 

我想知道的「我」參數的來源和目的,我看不出它在那裏來自(客戶端代碼)以及它用於什麼?作爲一名Java人,我會更容易理解這個概念,因爲我熟悉Java環境中的方法或'函數'參數。

這裏我沒有看到客戶端代碼(我認爲它在庫中),我也沒有看到它(i)在函數中是如何相關的,因爲它沒有被引用。

社區的某個人可以給出一個明確的解釋,或者轉介給我一個關於此的指南?

我理解每個函數和'this'引用的用途,因此除非您認爲它與此問題的未來觀察者相關,否則不需要解釋這些內容。

回答

13

在這種情況下,沒有必要聲明i。該each method的簽名在jQuery的文檔指出:

.each(function(index, Element))

正如你所看到的,它需要一個參數,該參數是一個函數,需要兩個參數,indexElement

在您的代碼中,iindex的標識符,它在每次調用時都會被jQuery傳遞給回調函數(每次迭代一次)。它還傳遞了第二個參數,但是您尚未爲其聲明標識符,因此只能通過arguments對象訪問它。

你可以看到什麼是日誌記錄arguments對象傳遞給回調:

​$("div").each(function() { //No arguments listed in callback signature... 
    console.log(arguments); //But arguments are still passed 
});​​ 

這裏是上面的working example

這裏的relevant code from jQuery itself(加註釋):

//... 
each: function(object, callback, args) { 
    //... 

    //Iterate over the matched set of elements 
    for (; i < length;) { 
     /* Call the callback in the context of the element, passing in the 
      index and the element */ 
     if (callback.call(object[ i ], i, object[ i++ ]) === false) { 
      break; 
     } 
    } 
} 
+0

因此,索引的用法隱藏在jQuery中,我們不需要知道比我們必須提供的更多的東西嗎? – thejartender

+0

它總是通過jQuery傳遞給回調函數(「Element」參數也是如此)。如果你想使用它,有助於給它一個名字(例如你的例子中的'i')。我已經添加了相關的jQuery源碼本身,這可能有助於進一步解釋。 –

+0

我會給你一個額外的投票,介紹我的日誌功能。它會幫助很多:)謝謝 – thejartender

2

當你調用$().each(),你傳遞一個函數參考.each()函數的工作方式是,對於jQuery對象中的每個元素,它將當前元素作爲上下文(即在函數調用中,this變量是當前元素)調用您給它的函數。

現在,當jQuery調用你給它的函數時,可以通過傳入可選參數,就像你在代碼中調用函數一樣。使用.each()時,無論何時調用您給它的函數,它都會傳入兩個參數:索引當前元素

這是因爲如果jQuery是調用它像:

$('div').each(foo); 

// results in something like 
for(var i=0; i < $('div').length; i++) { 

    // calling the foo function 
    foo(i, $('div')[i]); 

    // this is simplified, of course. 
    // this doesn't take into account the function context, or "this" variable. 
} 

您可能會發現the official documentation解釋它更好了。

1

正如它在API中所說'我'是索引。

,如果你想使偶數和凹凸體

象之間的差異這可能是有用的:

$(document.body).click(function() { 
    $("div").each(function (i) {   //Where does the 'i' come from? 
    if (i % 2 == 0) { 
     this.style.color = "blue"; 
    } else { 
     this.style.color = ""; 
    } 
    }); 
}); 
1

的這些參數的「原點」是「讓來自不同的prototype.js 「。
由於索引很少需要,所以傳遞參數的次序更加合理。

考慮這個例子:
哪個叫&函數最有意義?

$('.my-selector').each(modifyNodeA); 
$('.my-selector').each(function(){ 
    // this wrapper anonymous function is cruft 
    modifyNodeB(this); 
}); 
$('.my-selector').each(modifyNodeB); // this one won't work 
$('.my-selector').each(modifyNodeC); 
$('.my-selector').each(function(){ 
    // just using 'this' makes sense here.. it's evident that this is a jQuery closure 
}); 

function modifyNodeA(i, node) { 
    // this one works... but gotta have i in the func signature. 
    // it won't be used and doesn't make contextual sense 
    // can also use 'this', but where the heck did it come from.. it's not evident 
} 

function modifyNodeB(node, i) { 
    // 'i' could/should be an optional 2nd param 
    // this function could function on it's own 
} 

function modifyNodeC() { 
    // gotta use the magic 'this' scope var.. where did it come from? 
    // contextually, it would be nice to have the var passed... it is... as the 2nd param! 
} 

這裏簡單概括:

Why I STILL prefer Prototype over jQuery - Section 8 - Other Nit-picks

$.each$().each都先通過索引,然後價值 回調。這意味着如果我不需要這個索引,我不能像在Prototype中那樣將它從函數聲明中刪除掉。