2014-02-07 35 views
3

each jQuery的迭代器功能已語法類似於:jQuery的迭代函數

.each(function(index, element)) 

這似乎意味着匹配此聲明的函數將不得不採取2個參數。喜歡的東西:

function my_func(index, element){ 
    alert(index+":"+element); 
} 

對我來說,這給了2點可能的聲明:

$("li").each(my_func); 

$("li").each(function(index, element) {alert(index+":"+element);}); 

一是混淆了我,因爲我沒有看到indexelement傳遞到my_func 。在jQuery中有一些知道my_func需要2個參數each提供的魔術嗎?

其次,如果我宣佈

var my_func= function(index, element){ 
    alert(index+":"+element); 
} 

這會改變什麼。我的理解是,第一個是聲明和第二個是表達,但在這種情況下,他們應該表現相同?

最後,最each實現,我看到做這樣的事情:

$("li").each(function(){alert(this)}); 

都是可選的參數給each回調?

+0

在這兩種情況下,您都不會「看到」傳遞的參數。您傳遞的函數在集合中的每個項目上內部調用,並且它是傳遞參數的內部代碼。如果函數首先存儲在變量中,則不會有任何區別。 –

回答

5

方法來傳遞一個函數作爲回調

在此:

$("li").each(my_func); 

你只是傳遞一個參考my_func.each()方法。當它調用它時,每個方法本身都會將這兩個參數傳遞給該函數。如果你想訪問這兩個參數,那麼你可以在你自己定義的my_func中聲明它們作爲參數,但是你不需要。不管你是否申報,論據都會在那裏。

您可以在許多不同的方式申報my_func,並將:

var my_func= function(index, element){ 
    alert(index+":"+element); 
} 

// somewhat normal way and you can easily access the index and element arguments 
function my_func(index, element) { 
    // code here 
} 

// if you don't need index and element, you don't need to declare them 
// but they are still actually there and can be reached via the arguments object 
function my_func() { 
    // code here 
    console.log(arguments[0]); // index 
} 

聲明功能與var

之間的區別

function my_func(index, element){ 
    alert(index+":"+element); 
} 

很大程度上是時機之一。在第二種情況下,my_func被定義爲一個函數,只要它所在的javascript文件被定位並且被解析,並且它被定義的範圍變爲活動並且可以在範圍的頂部被聲明爲「好像」在其中被定義。當定義被提升到定義範圍的頂部時,這通常被稱爲「提升」。

在第一個,my_func不是一個函數,直到該JS的行在該JavaScript文件的正常執行流中執行。

除了時機,你幾乎可以交替使用這兩個。如果個人更喜歡function xxx()表單,因爲那麼我不必擔心函數是否在聲明運行之前被調用 - 但這實際上是個人風格偏好。


你一定要聲明回調參數

爲了您的最後一個問題,你只需要,如果你想使用它們的參數申報回調。在JavaScript中,無論您是否使用參數聲明函數(不在C++等語言中聲明它),函數都是完全相同的函數,因此如果您想按名稱訪問它們,則只需聲明它們即可。

javascript中的函數參數聲明是可選的。您可以聲明多於傳遞給該函數的內容,並且可以聲明小於傳遞給該函數的內容。在JavaScript中都不會導致任何類型的錯誤。

比方說,你有這樣的代碼:

function callWithDelay(t, fn, arg1, arg2) { 
    setTimeout(function() { 
     fn(arg1, arg2); 
    }, t); 
} 

使用,這將是定義一個函數有兩個參數,並將其傳遞的fn參數預期的方式。

function myFunc(msg, color) { 
    var obj = document.getElementById("error") 
    obj.innerHTML = msg; 
    obj.style.color = color; 
} 

callWithDelay(2000, myFunc, "Both first and last name are required", "red"); 

但是,您不必傳遞具有完全那些參數的函數。你可以不喜歡這樣(通過arguments對象訪問的參數,而不是按名稱):

function myFunc() { 
    var obj = document.getElementById("error") 
    obj.innerHTML = arguments[0]; 
    obj.style.color = arguments[1]; 
} 

callWithDelay(2000, myFunc, "Both first and last name are required", "red"); 

或者,你可以傳遞甚至不需要這些參數的函數:

function myFunc() { 
    document.getElementById("error").style.display = "none"; 
} 

callWithDelay(2000, myFunc); 

callWithDelay函數不關心你傳遞它的函數引用。它可以字面上是任何功能。 callWithDelay函數將兩個參數傳遞給它調用時傳遞給它的回調函數,但它純粹由接收函數決定是否使用這些參數。在最後一個例子中,當它被調用時,我將最後兩個參數從callWithDelay中刪除。當你離開參數時(在通話列表的末尾),該參數就是undefined。在javascript undefined是一個合法的值。因此,當我將它們從callWithDelay(2000, myFunc)的電話中刪除時,它們是undefined,因此undefined是作爲其兩個參數傳遞給myFunc回調的內容。在這種情況下,由於沒有使用這些參數,所以沒有人在意他們是undefined


函數重載 - 檢查什麼樣的參數類型被傳遞

在JavaScript中,您還可以檢查被傳遞給函數的是什麼類型的參數,並相應地調整自己的行爲。例如,假設你有一個簡單的函數,HIDS DOM元素:

function hide(elem) { 
    elem.style.display = "none"; 
} 

// usage 
var obj = document.getElementById("test"); 
hide(obj); 

此函數假定ELEM是DOM元素,如果這是傳遞纔有效。但是,如果我們還想讓某人通過一個元素的id會怎麼樣。我們可以檢查傳遞給hide的參數,看看它是否是一個字符串,如果是的話,我們可以把它看作一個id值。

function hide(elem) { 
    // if a string was passed, find the DOM object using that string as an id 
    if (typeof elem === "string") { 
     elem = document.getElementById(elem); 
    } 
    elem.style.display = "none"; 
} 

// first usage 
var obj = document.getElementById("test1"); 
hide(obj); 

// second uage 
hide("test2"); 

現在,假設我們想不僅允許一個單一的DOM元素傳遞,而且DOM元素的數組,因此函數將數組中的每個DOM元素進行操作。

function hide(elem) { 
    // if a string was passed, find the DOM object using that string as an id 
    if (typeof elem === "string") { 
     document.getElementById(elem).style.display = "none"; 
    } else if (typeof elem === "object" && Object.prototype.toString.call(elem) === "[object Array]") { 
     // an array was passed 
     for (var i = 0; i < elem.length; i++) { 
      elem[i].style.display = "none"; 
     } 
    } else { 
     // only a single DOM element was passed 
     elem.style.display = "none"; 
    } 
} 

// usages 
hide(obj); 
hide([obj1, obj2, obj3]); 
hide("test"); 
+0

我假設當你聲明「my_func」變量時,它也是有作用域的 - 而不是全局性的。正確? –

+0

@drew_w - 是的,'var my_func = function(){}'只存在於聲明的範圍內,但對於另一種定義函數的方法也是如此。函數可以在其他函數中定義,然後將其範圍限定在該函數內。範圍的兩種方法之間沒有真正的區別。 – jfriend00

+0

@ jfriend00非常感謝你的回答。你能否詳細說明「函數是否完全相同的功能,無論你是否用參數聲明」都是一點?我的思想更多的是Java/C世界,我不太明白這意味着什麼。 –