2014-10-22 79 views
-2

對我來說,下面的代碼似乎很合理:爲什麼在這裏需要更復雜的jQuery模式?

$("#oneButton").click(
    alert("hello"); 
); 

這似乎是說,被點擊OneButton時,請彈出一個警告說「你好」。

但是,實際上,無論按鈕是否被點擊,都會彈出警報。

必須在一個匿名函數中包裝alert("hello");,然後THEN(並且只有這樣)彈出的警報將取決於單擊該按鈕。對我來說,這似乎不必要地令人費解。

爲什麼jQuery的設計者認爲它可以接受上述代碼中的警報,即使按鈕沒有被點擊時也會彈出,這一定是有原因的。這是什麼原因?

+0

這是開始看起來像一個「主要基於輿論」的問題。 – Paul 2014-10-22 06:15:51

+0

很難知道'alert'(也可能是'myFancyFunction')是否會在稍後發生某些事情,或者產生一些可以在稍後發生的事情。 – Thilo 2014-10-22 06:17:16

+0

在這裏你有一個很好的文章:http://javascriptissexy.com/understand-javascript-callback-functions-and-use-them/ – melancia 2014-10-22 06:19:53

回答

5

公平的問題,我想,雖然我不是來了吧:)

讓我們打破這一點傲慢的粉絲:

object.method(function() { 
    alert('hi'); 
}); 

你的問題是,爲什麼可以」我跳過匿名函數?

我們真的在這裏做什麼,告訴method稍後再執行一些操作。正在執行的是作爲一項功能提供的。

我們可以簡單地給它一個函數的引用!

object.method(alert); 

這裏的問題,我們已將它的功能,但現在我們不能發送的任何參數。如果我們想要沿着method來建築,我們必須使用()

只要包含這些字符,alert將被執行,並且alert的結果將被髮送到method

現在爲什麼不能通過參考發送?原因很簡單,你需要一些方式也傳遞函數的結果作爲參數傳遞給另一個函數,以及JavaScript引擎無法區分,如果你的目的是:

  • 發送函數的結果作爲這個函數的一個參數,或者用一些參數發送函數的引用給另一個函數。

上的功能使用()意味着幾乎所有的編程語言立即調用它,JavaScript是沒有什麼不同。

有一種變通方法:

object.method(alert.bind(this, "hi")); 
+0

'alert.bind'非常好。但它只適用於單個功能,而不適用於整個功能塊。 – Thilo 2014-10-22 06:18:54

+0

好吧,OP的例子本來就是一個語法錯誤,只要有一個以上的語句。 – Evert 2014-10-22 06:19:41

+0

@Evert:我想這就是他所抱怨的。如果我們假設在語言語法中修復它,它也應該支持塊。 – Thilo 2014-10-22 06:20:47

0

問題是Javascript沒有宏(具有Lisp的含義),並且向函數提供「代碼」的唯一方法是傳遞函數/閉包對象。

click只是一個常規的方法,並接受點擊按鈕時執行的「代碼」參數。然而,對於任何參數,傳遞給click的表達式在進行調用時進行評估,而在用戶單擊該按鈕時不會進行評估。 要讓click按照你喜歡的方式工作,語法應該處理click與其他函數調用不同,這就是Lisp允許使用宏而不是函數的例子。 Javascript沒有宏,語法在語言中是固定的:它沒有click特殊格式,而且你不能創建一個。

這種情況並不是那麼糟糕,因爲Javascript語法允許內聯匿名函數,所以基本上你只需要在呼叫站點用function(){...}包裝你的「代碼」參數就可以使它工作。

在Python中,比較煩人的是,因爲只有極其簡單的函數可以內聯指定,因爲lambda表單可用於指定匿名內聯函數,但具有嚴重的限制,並且不允許任何語句,而只是單一表達。

0

由於.click()是一個函數,它可能需要一個/某些參數/ s才能正確使用。

.click()只會觸發事件。

但是.click(parameter)將在事件觸發後執行參數中的操作。在這種情況下,parameter是一個回調函數,即在主函數完成後調用的函數。 但是對於要調用的回調,您將不得不創建一個函數。

無論是通過命名一個:

function alertThis(){ 
    alert('hello'); 
} 

$("#oneButton").click(alertThis); 

或者:

$("#oneButton").click(function(){ 
    alert('hello'); 
}); 
0

語言只能提供功能(看CoffeeScript的)一個更簡潔的語法,但它是OK的庫函數來執行立即,所以你可以包裝它們並在需要時傳遞代碼。

你有什麼建議呢?我只能想到一個替代方法,即原始API返回自己的功能,但是當你需要將多個組合原語(即使是通過語言直接語法的支持),這將導致醜陋代碼:

$(btn).onClick(alert().andThen(blink()).andThen(log())); 

而且還您將被迫致電

alert()() 

當您需要立即顯示對話框時。

+1

強與寬鬆打字在這裏扮演一個角色。在C++或Java中,可以非常詳細地說明onClick(handler)的正確處理參數是什麼,這樣定義它並將其發送到onClick()的自然語法將防止意外地調用它,並且如果您仍然使用它,它可能會生成編譯時異常。但是隨着Javascript的寬鬆打字,函數的參數被允許爲任何東西...... – Paul 2014-10-22 06:21:47