2013-10-01 31 views
1

使用jQuery for-loop非常慢,這就是我考慮更頻繁地使用常規for-statement的原因。爲了具有對當前元素的直接訪問,我發現下面的語法(規則陣列,而不是爲當然對象):增強型Javascript for-statement安全使用?

for (var i = 0, e; e = array[i]; i++) { ... } 

其中e在迴路表示的當前元素。

此語法在所有瀏覽器中都可以安全使用嗎?


加成

OK,我想這可能是工作,但它再也不是那麼有用了很短的符號:

for (var i = 0, e; (e = array[i]) !== void(0); i++) { ... } 

謝謝大家的回答!

+0

你可以在這裏測試它:http://tuttijs.com/(並請與我們分享你的結果:)) – Reeno

+5

只要'數組[i]'不是一個錯誤的值在循環的中間。這取決於你的意思是「安全」 – Ian

+1

這是極其基本的語言功能的組合。它保證工作。 – SLaks

回答

1

我不建議。你看,如果你的陣列看起來像這樣的例子:

array = ["lala", 078, false, 992, "kas"]; 

然後你的循環只會經歷了前兩個,因爲術語e = array[i];將返回false,因爲數組中的第三項是字面上假的。 這是更好的:

for (var i = 0, e; (e = array[i])===undefined; i++) { ... } 

確保沒有一個覆蓋未定義的變量,例如通過使用閉包:How does this JavaScript/JQuery Syntax work: (function(window, undefined) { })(window)?

+0

因爲真的可以覆蓋'undefined',所以最好使用'(e = array [i])!== void(0)'? –

+0

Btw:你可能是指'(e = array [i])!== undefined'? –

+1

@SimonFerndriger你應該能夠可靠地檢查'typeof(e = array [i])undefined!=='undefined'' – 2013-10-01 14:36:50

7

這不是一個很好的循環。考慮這個數組:

var array = [0, 1, 2, 3]; 

將停止第一個元素,因爲0是falsey值。同樣的,

var array = ["foo", "bar", false, "hello"]; 

它只會得到"foo""bar"


考慮使用這種循環

for (var i=0, len=array.length; i<len; i++) { ... } 

它的工作原理無處不在,只計算array.length一次,而且是大量的高性能。


每T.J.的評論中,ARGS i及以上len的範圍將存在於您的當前功能。所以要小心不要發生可變的衝突。

一個有點常見(但笨重)的防範方法是在_的前綴變量。這樣

for (var _i=0, _len=array.length; _i<_len; _i++) { ... } 
+1

大+1。在所有情況下,請記住,這些變量不是**範圍的循環,而是函數。 (ES6將有'let',將範圍擴展到循環。) –

+0

感謝您的評論,T.J ..我給你留言在我的編輯。 – naomik

1

作爲naomik points out,環的這種形式將打破如果任何數組元素的具有falsey值。 Falsey值是false,nullundefined,""0NaN。所以它可以工作,例如,一個非空對象引用的數組。不是一堆字符串或數字。

但是,如果你的問題是關於語法,那麼是的,它是「安全」的,因爲它將在所有JavaScript引擎中工作(並且在假元素上失敗)。您所依賴的關鍵位是:

  1. 訪問超出數組末尾的元素(例如,在array[array.length])會給你一個falsey值(undefined),而不是拋出一個異常,並

  2. ,一個賦值表達式(e = array[i])的結果是,被分配的值。

是的,這兩個都是可靠的。 (當然,#1是可靠如果陣列真的是JavaScript數組。主機提供的陣列狀物體可能有所不同。)


在任何情況下,請注意,既不i也不e僅作用域到環路。 ES6將有let,這將是,但聲明與var聲明變量的範圍,以他們的功能。