2014-12-02 85 views
1

考慮這段JavaScript代碼:應用動態參數的JavaScript功能,但推遲調用

var someArg = "Hello"; 
elem1.onclick = function() { foo(someArg); }; 
someArg = "Bye"; 
elem2.onclick = function() { foo(someArg); }; 

我想調用FOO的說法「你好」當我點擊elem1,但是,上面的代碼工作的方式, foo每次調用「Bye」。

基本上,我想申請someArg爲foo但不實際調用FOO,直到後來。

回答

3

你做到這一點,通常的方法是使用生成器功能:

var someArg = "Hello"; 
elem1.onclick = buildHandler(someArg); 
someArg = "Bye"; 
elem2.onclick = buildHandler(someArg); 

function buildHandler(arg) { 
    return function() { foo(arg); };; 
} 

...或Function#bind

var someArg = "Hello"; 
elem1.onclick = foo.bind(null, someArg); 
someArg = "Bye"; 
elem2.onclick = foo.bind(null, someArg); 

無論哪種方式,你正在做的是創造一個新的功能是什麼那麼在撥打電話時,請撥打foo,並將的值傳遞給您。您的原始代碼不起作用的原因是這些函數關閉了變量someArg,而不是它們創建時的值。所以,因爲他們在被調用時使用了這個值,所以你沒有得到你想要的值。上述兩種解決方案(以不同的方式)都創建了一些函數,它們可以在創建函數時關閉某些值,而不是創建函數。

+0

如果您使用的是UnderscoreJS或Lodash,則執行相同操作的另一種方法是使用'_.partial()'。 – GregL 2014-12-02 01:52:11

+0

@GregL:或PrototypeJS的'咖喱',但該列表可能會很快... – 2014-12-02 01:53:02

+0

非常感謝,這正是我所期待的。也許我應該在OP中提到,我知道問題是什麼,爲什麼會發生,我只是在尋找解決方案,但感謝您再次解釋。 – 2014-12-02 02:10:52

0

這是因爲,這是Javascript的工作原理。你將不得不用不同的變量調用foo()來達到這個目的。我只看到一個辦法解決這個..

var someArg1 = "Hello"; 
var someArg2 = "Bye"; 
elem1.onclick = function() { foo(someArg1); }; 
elem2.onclick = function() { foo(someArg2); }; 

這是因爲,只有當你調用foo() foo將得到的參數和參數將是可變someArg在調用該點的值。而且由於Javascript在頁面加載時執行函數調用之外的所有內容,因此它在頁面加載時也會執行someArg = 'Bye'

0

你有它設置,JavaScript是幾乎立即就首先定義它後更改負載someArg的定義方式。你需要使用像這樣的另一個變量:

var someArg = "Hello"; 
elem1.onclick = function() { foo(someArg); }; 
var someArg2 = "Bye"; 
elem2.onclick = function() { foo(someArg2); }; 

或變量傳遞到函數,並定義變量別處:

elem1.onclick = function(someArg) { foo(someArg); }; 
elem2.onclick = function(someArg) { foo(someArg); }; 
//Some stuff happens.... 
thisVariable = 'stuff happened'; 
elem2.onclick(thisVariable); 

這將導致FOO被稱爲用「的東西發生了」論據。

希望這會有所幫助。如果沒有,請提供關於您的用例的更多細節,以便我們可以更多地集中我們的答案。

+0

這並不能解決我的問題,因爲在我的情況下,someArg是一個循環變量,它會改變未知次數,所以我不能只爲不同的賦值使用不同的變量名稱。 但是,您的文章可能會說明爲什麼我的代碼不適用於不知道的人。 – 2014-12-02 02:04:10