2012-12-20 56 views
14

我已經看到循環內部的匿名函數在一兩處引發網絡新的範圍,並想知道它是否有意義。在javascript for循環中使用匿名函數

例如:

var attr, colors = ['green','blue','red']; 

for (attr = 0; attr < colors.length; attr++) { 
    (function() { 
     var colorAttr = colors[attr]; 

     // do something with colorAttr 
    })(); 
} 

我理解它是與保持內部的for循環的清潔範圍,但在什麼情況下會變成這樣有必要嗎?在任何需要在for循環內聲明新var的地方進行此操作是否是一種好的做法?

+0

這裏是一個閉環循環有意義的例子:http://stackoverflow.com/questions/1552941/variables-in-anonymous-functions-can-someone-explain-the-following –

+1

'attr'隨着循環進行,所以如果你在回調函數中使用'colors [attr]',它將不會引用你實際需要的'colors [attr]'。 – Blender

+0

僅在等待某件事完成時才使用異步呼叫。在這種情況下,追蹤'colors []'變化可能會有問題。 – mkey

回答

28

當你有內部函數不立即執行,作爲循環的一部分。

var i, colors = ['green', 'blue', 'red']; 

for (i = 0; i < colors.length; i++) { 
    var color = colors[i]; 
    setTimeout(function() { 
     alert(color); 
    }, i * 1000); 
} 

// red 
// red 
// red 

儘管var color位於循環內,循環沒有範圍。實際上,每個循環迭代使用的變量只有一個。所以當超時激活時,它們都使用相同的值,即循環設置的最後一個值。

var i, colors = ['green', 'blue', 'red']; 

for (i = 0; i < colors.length; i++) { 
    (function(color) { 
     setTimeout(function() { 
      alert(color); 
     }, i * 1000); 
    })(colors[i]); 
} 

// green 
// blue 
// red 

這一個捕獲每次迭代的值到一個函數的參數,它創建一個範圍。現在,每個函數都獲得它自己的color變量版本,當在該循環中創建的函數稍後執行時,該變量不會更改。

+1

ohhhhhhhhhh這是有道理的 – Evan

+0

我知道你寫這篇文章已經有一段時間了,但它(仍然)非常有幫助。謝謝!! – Jonas

2

你快到了。如果你的通過attr值進入你的自調函數作爲參數,它只會在你的代碼段中有意義。這樣一來,它可以存儲其自己的範圍對象內的變量

(function(attr) { 
    var colorAttr = colors[attr]; 

    // do something with colorAttr 
})(attr); 

現在分別激活對象詞法環境記錄(這是ES3和ES5範圍的對象)都會有一個條目無論什麼值落後於attr,因此其關閉

+0

「如果您將attr值作爲參數傳遞給您的自調用函數,它在您的代碼片段中才有意義。」 IIFE立即執行,無論'attr'值是否作爲參數傳入,都將'colors [attr]'存儲在'colorAttr'中。當然傳遞參數是一種乾淨的方法。 – zzzzBov