2013-01-16 18 views
2

我有這個JavaScript函數:爲什麼我必須在匿名函數中附加一個Javascript函數調用,以免它立即被調用?

function Card(term, def, terms, curTerm) { 
    this.term = term; 
    this.def = def; 
    this.terms = terms; 
    this.curTerm = curTerm; 

    this.show = function() { 
     that = this; 
     var html = createCard(that.term, that.def); 
     $('body').append(html); 
     $('input[type=text]').focus(); 
     $('.answer').on('click', function(event) { 
      event.preventDefault(); 
      answer = $(this).parent().serializeArray()[0].value; 

      // answer correct 
      if (that.term === answer) { 
       $('.card').addClass('correct'); 
       $('form').replaceWith('<h2>Correct! ' + that.term + '</h2>'); 
       setTimeout(function() {that.destroy(terms, curTerm + 1);}, 1500); 

      // answer incorrect 
      } else { 
       $('.card').addClass('incorrect'); 
       $('form').replaceWith('<h2>Incorrect! ' + that.term + '</h2>'); 
       setTimeout(function() {that.destroy(terms, curTerm);}, 1500); 
      } 
     }); 
    }; 

我有問題,該生產線是setTimeout(function() {that.destroy(terms, curTerm + 1);}, 1500);。本來我有setTimeout(that.destroy(terms, curTerm + 1), 1500);,但它沒有設置超時,它只叫that.destroy。爲什麼在匿名函數中不會立即調用它?這與封閉有什麼關係?因爲看起來我不得不創建一個閉包,但我還沒有弄清楚他們知道的確實如此。

任何想法將不勝感激。

+1

因爲你正在傳遞一個函數,這是setTimeout期望的。 'setTimeout(that.destroy(terms,curTerm + 1),1500);'立即執行'destroy',並將'destroy'的返回值傳遞給'setTimeout' – Shmiddty

回答

6

在你的第一個setTimeout()通話,這樣的:

that.destroy(terms, curTerm + 1) 

是一個函數調用表達式。它的評估是爲了建立一組參數值來呼叫setTimeout()

當你把它包裝在一個匿名函數,即(匿名)函數叫,因爲你不與函數調用操作—的參數組合列表後綴它。

因此:形式

something (p1, p2, ... pn) 

的表達是指在參數列表中評估每個參數之後調用的「東西」引用的函數,然後使用該值作爲較大的表達式上下文進行。它總是意味着在JavaScript中。沒有語法可以說「這是我希望你稍後調用的函數,還有一些參數需要傳遞」。 (有一個功能做,現在— .bind()的函數原型—但沒有特別語法

+0

謝謝!這是完全合理的 - 不知道爲什麼我沒有想到過。因此,對於.bind(),如果我說'that.destroy(terms,curTerm + 1).bind()'會阻止它執行直到調用'setTimeout()'? – chromedude

+0

@chromedude不,使用'.bind()'你可以調用'that.destroy.bind(that,terms,curTerm + 1)'並將其傳遞給setTimeout。該調用返回一個函數,該函數在調用時調用「銷燬」函數。 – Pointy

+0

啊......這很有道理。謝謝! – chromedude

1

這僅僅是JavaScript語法的一部分。

function name() {}聲明的函數和name()調用它。您也可以立即使用語法(function(){})()調用匿名函數。

還要注意的是,你可以通過功能其中一個匿名函數,否則將是適當的,如:

setTimeout(that.destroy, 1500) 

當然你不能改變的參數在這種情況下。

1

當JavaScript解釋器看到someFunction(param)時,它立即調用方法someFunction並將參數傳遞給參數param。換句話說,當你這樣做時:

setTimeout(someFunction(param), 1000); 

......你正在傳遞setTimeout someFunction(param)的結果。你能傳遞someFunction作爲第一類成員是這樣的:

setTimeout(someFunction, 1000, param); 

這樣,你傳遞的setTimeout someFunction的定義。注意在這種情況下通過param在IE中不起作用。

此外,請參閱http://www.helephant.com/2008/08/19/functions-are-first-class-objects-in-javascript/

相關問題