2013-11-14 168 views
2

關於循環中臨時變量的最佳實踐是什麼?它是更好地做一些事情,如:最好在循環內部或外部聲明臨時變量?

some_array.forEach(function(item) { 
    var temp_obj = {}; 
    // do some operations with temp_obj 
}); 

OR

var temp_obj; 
json.forEach(function(item) { 
    temp_obj = {}; 
    // do some operations with temp_obj 
}); 

我總是假設有在性能上沒有差異,但我每次使用它的時候,我不知道我在下面好的做法...

+2

@ user2356705該問題代表了一種非常不同的情況。 – Pointy

+1

IMO,儘可能將變量保持在最近的範圍內,所以在這種情況下,在回調中。 –

回答

2

前兩個評論是非常錯誤的(在撰寫本文時,有些已被刪除)。由於forEach將函數作爲參數,所以會形成閉包,並且變量提升不適用。

要回答你的問題:取決於上下文。你不應該使用全局變量,但是如果第二個例子中的代碼被封裝在其他函數中,那麼它是可取的,因爲變量只能被分配一次(順便說一下,數字2說明了閉包的概念,功能)。

+1

*爲什麼*「因爲變量只能初始化一次」*更可取? –

+0

_「只初始化一次」_ - 你的意思是_「只分配一次」_?每當賦值被評估時它都被設置。 –

+0

@Ted Hopp你是完全正確的 - 我當時馬虎。更正了我的答案。如果對象具有某些實際內容/明顯大小,則每次都必須進行初始化,但由於它是空白的,因此只會被分配。 – jacktheripper

1

沒有好的做法,這一切都取決於你試圖實現的範圍。

循環內意味着你的var將不能在循環外部訪問。還有一些與閉包有關的其他事情。一個resource例如

2

取決於我們正在談論什麼樣的表現。無論如何,我懷疑其中的任何一個都會顯示出明顯的差異。還要記住,引擎可能會應用優化,而生成的實際可能會有所不同。


some_array.forEach(function(item) { 
    var temp_obj = {}; 
    // do some operations with temp_obj 
}); 

在這種情況下,變量temp_obj將以更快的速度查找,因爲它是在本地範圍內定義。這可能是可取的。因爲局部變量沒有被創建的函數的


var temp_obj; 
json.forEach(function(item) { 
    temp_obj = {}; 
    // do some operations with temp_obj 
}); 

創建時間可能會較少。


當然,在局部變量和自由變量之間也存在行爲差異。自由變量將在每個函數調用之間「共享」。

0

這實際上是一個有趣的問題,主要是因爲JavaScript處理範圍的方式。有幾條評論提到這個問題以前已經得到了答案,但它在我看來並沒有。請注意,這是一個很大的區別:因爲在第二個回調提供範圍的事實

someArray.forEach(function(item){}); 

:這

for(var i = 0; i < someArray.length; i++){} 

。如果你正在使用for循環,如果你在函數的內部或外部聲明變量,字面意思並不重要,因爲無論如何變量將會變爲hoisted

如果您具體詢問,是否在函數內部或外部聲明變量很重要,因爲該函數提供了範圍,並且該變量不會被提升。如果你關心性能,你應該在回調之外聲明它,因爲變量只會被創建一次。但是,如果您不需要在回調之外使用該變量,我實際上會建議在回調中定義變量。在我看來,它使得代碼更易於閱讀,除非你的臨時對象非常昂貴,它不會以任何明顯的方式影響性能。

+0

*「除非你的臨時對象的內存非常昂貴,它不會以任何明顯的方式影響性能」*從例子看來,對象實際上是在循環內創建的,無論變量是在哪裏定義的。你是說分配一個大對象到局部變量的性能比分配給一個更高範圍的變量要少嗎? –

+0

@FelixKling - 這是一個非常好的觀點,我完全錯過了。在OP發佈的情況下,仍然沒有任何區別,因爲分配總是在循環中發生。我的意思是在調用forEach之前分配對象,然後在回調中使用它。代碼更高性能的唯一方法是如果臨時對象是內存昂貴的,並且只定義一次。 – TwentyMiles

相關問題