簡體   English   中英

for循環中的javascript'let'和'var'

[英]javascript 'let' and 'var' in for-loops

在我搜索具體數字以支持Javascript中const關鍵字的使用時,我偶然發現了所有三個變量聲明類型var,let和const之間的性能比較。 我不喜歡測試設置,所以我創建了一個簡化版

我沒想到會有太大差異,Firefox的測量結果符合我的預期:

Firefox 52上的jsPerf結果

但在Chromium中發生了一些奇怪的事情:

Chrome 57上的jsPerf結果

不僅所有測試結果都顯着降低,而且let循環內部分解為速度的一小部分。

我決定在Browserstack中運行測試,以確保它不是我古怪的Linux設置。 在Windows 10上使用Firefox 53Chrome 58也是如此。我甚至測試了較舊的Chrome 50並獲得了相同的行為。

到底是怎么回事? 這是一個錯誤嗎?

編輯:有人評論說,循環可能只是因為它什么都不做而被優化掉了。 為了表明,事實並非如此,我改變了測試

當您使用let的for循環必須創建一個新的范圍來處理循環變量正確的一生身體,然而,在許多情況下,可以優化掉額外的代碼和運行。 例如,考慮以下代碼:

let sum = 0;
let fns = [];
for (let i=0; i < 1000; i++) {
  function foo() { sum += i; }

  fns.push(foo);

}

當你通過babeljs運行它時,你可以看到它產生的等效ES5代碼包括一個函數調用,以保持正確的變量生命周期:

var sum = 0;
var fns = [];

var _loop = function _loop(i) {
  function foo() {
    sum += i;
  }

  fns.push(foo);
};

for (var i = 0; i < 1000; i++) {
  _loop(i);
}

但是,babel非常聰明,如果你不做任何需要延長循環變量生命周期的事情,它只需使用一個普通的for循環,並且內聯體。 所以你的代碼:

for (let i=0; i < 1000; i++) {
  true;
}

可以顯示完全等同於:

for (var i=0; i < 1000; i++) {
  true;
}

我的猜測是,Chrome內部發生了非常相似的事情,但他們還沒有優化他們不必保持循環變量存活的情況。

看看我在這個例子的頂部使用的代碼如何在Firefox和Chrome中進行比較會很有趣,因為我懷疑它們最終應該同樣緩慢。 你應該注意像空循環這樣的計時,因為結果可能會因為優化而偏向於實際代碼的正常情況。

這是因為let關鍵字對規范來說有點新,只適用於本地范圍。 在Chrome中,它似乎尚未優化,但這應該只是時間問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM