2015-07-22 65 views
0

我是一個javascript新手,試圖圍繞這段代碼考慮一下。 我在這裏得到了http://brackets.clementng.me/post/24150213014/example-of-a-javascript-closure-settimeout-inside這是一個立即調用的函數表達式嗎?

我還是很難理解它。因爲它涉及一些我不熟悉的模式。

// output 0-9, seperated by 1 sec delay. 
for (var i = 0; i < 10; i++) { 
    setTimeout(function(x) { 
     return function() { 
      console.log(x); 
     }; 
    }(i), 1000*i); 
} 

(i)在這段代碼中的含義是什麼?

function(x) { 
    return function() { 
     console.log(x); 
    }; 
}(i) 

我認爲這是一個立即調用的函數表達式。 但沒有爲正確的語法是:

(function() { 
    // some code 
})(); 
+0

如果有人在這裏感興趣的是對相同代碼的另一種解釋。 http://stackoverflow.com/questions/12930272/javascript-closures-vs-anonymous-functions?rq=1 –

回答

2

也就是說,確實是一個IIFE。你引用的語法是一個0參數的IIFE;您詢問的語法是1個參數的IIFE。它將在內部代碼中將i分配給x。比較:

var print0 = function() { 
    console.log("Hello!"); 
}; 
print0(); 

是(隔離),相當於

(function() { 
    console.log("Hello!"); 
})(); 

這樣的名字:您創建一個函數,然後立即調用它。

但是,如果你想要一個說法,沒有什麼變化:

var print1 = function(name) { 
    console.log("Hello, " + name); 
}; 
print1("George"); 

是(隔離),相當於

(function(name) { 
    console.log("Hello, " + name); 
})("George"); 

括號這裏確保函數的定義將被視爲一個表達而不是聲明。還有其他的方法來確保,一個常見的一種是

!function() { 
    console.log("Hello!"); 
}(); 

(但我們有理由喜歡的括號內。)由於您使用它作爲參數傳遞給setTimeout調用,它不可能是一個聲明,所以這些黑客是沒有必要的。它仍被稱爲「立即調用函數表達式」,因爲您仍在構造函數表達式並立即調用它。

此處使用IIFE的原因是「捕獲」變量i的值,而不是x的位置。沒有關閉技巧,你會得到10個超時,全部輸出10(當console.log解決時,由x表示的位置的值)。

+0

我明白了!感謝您的快速回復男士欣賞它 –

0

是的,和(i)是呼叫參數列表。詳細解釋請看here。在這種情況下,分組圓括號是毫不含糊的,因爲它是對函數調用的一個參數,因此也是表達式。

術語IIFE不僅指這種模式的陳述形式,其中parenthesis would be necessary

+0

該鏈接是非常有幫助的,謝謝! :) –

0

在你的直接調用函數的示例中,可選項是可選項。

(function() { 
    // some code 
})(); 

可以重新寫爲

function() { 
    // some code 
}(); 

在例子中函數的調用i成爲函數定義的x

function(x) { // x = 1 
    return function() { 
     console.log(x); // x = 1 
    }; 
}(1) 
相關問題