2012-10-06 60 views
3

我是一個C + +(Qt)開發人員,並知道一點JS。我無法理解以下代碼的一部分。你能幫我解決這個問題嗎?JS關閉查詢

function augment(withFn) { 
    var name, fn; 
    for (name in window) { 
     fn = window[name]; 

     if (typeof fn === 'function') { 
    // **Not able to understand below code.** 
      window[name] = (function(name, fn) { 
       var args = arguments; 
       return function() { 
        withFn.apply(this, args); 
        fn.apply(this, arguments); 

       } 
      })(name, fn); 
    // **In above code I understood everything else except this last line. 
    // Why whole function is in circular bracket? Why it ends with (name, fn); 
    // What is the meaning of this? 
     } 
    } 
} 

augment(function(name, fn) { 
    console.log("calling " + name); 
}); 
+0

@Quentin:實際上它不僅僅是關於語法,還有它爲什麼在那裏使用 – zerkms

+0

+1,所有的@zerkms的例子都非常好。 – SunnyShah

回答

1

自行執行的匿名函數是解決循環中閉包問題的常用方法。

所以它實際上是一個匿名函數,它是通過傳遞的參數立即聲明和執行的。

實際上name參數在那裏沒用,因爲它沒有被使用,但是如果你沒有這樣做 - 那麼只有最後的fn參數會作爲參考被傳遞。

問題的演示:http://jsfiddle.net/zerkms/nfjtn/

解決方案(使用自執行匿名函數):http://jsfiddle.net/zerkms/nfjtn/1/

+0

有一個問題,效率如何?定義一個函數變量並在每個循環中「應用」它不會更快嗎? – SJuan76

+0

我相信它會更快,是的 – zerkms

+0

@zerkms,非常感謝與例子的答案。如果可能的話,請給我提供您最喜歡的鏈接,以瞭解這些JS概念。 – SunnyShah

1

嗯,首先:

(function f(param) { alert(param); })("Hello world"); 定義函數並立即執行它。

function f(param) { alert("This: = " + this + ". Param=" + param); } 
f.apply(window, "Hello world"); 

呼叫中的window上下文中的函數f (即功能「認爲」其屬於window對象)使用參數params

function(param)返回到匿名函數的參考。那就是:

var f = function(param) {...}; f("Hello world");是類似於:

(function(param){...})("Hello world"); 
1

括號(你所說的「圓括弧」)的表達式是一個匿名函數。 (name, fn)在它的結尾意味着應該用這些參數調用該函數,並且返回值被分配給window[name]。這大約相當於:

tempfn = function(name, fn) { /* body */ }; 
window[name] = tempfn(name, fn); 
1

通常位於C你必須定義(也許聲明)

int anon(string name, void* function) { 
} 

和調用函數

anon(name, function); 

圓內的部分括號是匿名函數的聲明;立即使用(name, fn)參數調用該參數。

把它看作(注:可能JS是一個有點生疏,所以一些語法錯誤是可能的)

var fn2 = (function(name, fn) { 
    var args = arguments; 
    return function() { 
     withFn.apply(this, args); 
     fn.apply(this, arguments); 
    }); 

而且,在循環

window[name] = fn2.apply(name, fn);   
1

你正在試圖繞過的問題此後在循環中引用namefn。如果你只是做window[name] = function() { alert(name); }所有你分配的函數將總是使用name最後設置的值,而不是你在循環中定義該特定函數時的值。爲了解決這個問題,可以創建一個函數,該函數可以立即使用正確的值進行調用,並以這種方式在新的閉包中保護它們。你可以在這個SO問題中閱讀更多關於它的信息:JavaScript closure inside loops – simple practical example