回到基礎:用循環優化 JavaScript 程序

翻譯:瘋狂的技術宅 medium.freecodecamp.org/how-to-opti…javascript

Photo by Zachary Young on Unsplash

對於提升 JavaScript 程序的性能這個問題,最簡單同時也是很容易被忽視的方法就是學習如何正確編寫高性能循環語句。本文將會幫你解決這個問題。前端

咱們將看到 JavaScript 中主要的循環類型,以及如何針對它們進行高效編碼。java

如今開始!數組

循環性能

談到循環性能,爭論的焦點始終會集中到關於應該使用哪一種循環,哪一個是速度最快、性能最好的?事實上,在 JavaScript 提供的四種循環類型中,只有一種比其餘循環慢得多 ——  for-in 循環。 對循環類型的選擇應基於你的需求而不是性能問題app

有兩個主要因素有助於改善循環性能 —— 每次迭代完成的工做迭代次數oop

在下面的內容中,咱們將會看到經過對這兩點的優化,能夠對循環的總體性能產生積極的影響。性能

For 循環

在 ECMA-262(定義JavaScript的基本語法和行爲的規範)第三版中,定義了四種循環類型。第一個是標準的 for 循環,它與其餘類 C 語言的語法相同:學習

for (var i = 0; i < 10; i++){
    //循環體
}
複製代碼

這多是最經常使用的 JavaScript 循環結構。要了解應該怎樣對其進行優化,須要先進行一些分析。測試

解析

for 循環由四部分組成:初始化,預測試條件,循環體和後執行。它的工做方式以下:首先,執行初始化代碼(var i = 0;)。而後是預測試條件(i <10;)。若是預測試條件的計算結果爲 true,則執行循環體。以後運行後執行代碼(i ++)。優化

優化

要優化循環中的工做量,第一步是最小化對象成員和數組項查找的數量。

還能夠經過反轉順序來提升循環的性能。在 JavaScript 中,反轉循環對循環的性能提高不大,除非你消除了額外的操做。

// 原始循環
for (var i = 0; i < items.length; i++){
    process(items[i]);
}
// 最小化屬性查找
for (var i = 0, len = items.length; i < len; i++){
    process(items[i]);
}
// 最小化屬性查找並反序
for (var i = items.length; i--; ){
    process(items[i]);
}
複製代碼

While 循環

第二種是 while 循環。下面是一個簡單的預測試循環,由預測試條件和循環體組成。

var i = 0;
while(i < 10){
    //循環體
    i++;
}
複製代碼

解析

若是預測試條件的計算結果爲 true,則執行循環體。若是不是 —— 它就會被跳過。每一個 while 循環均可以用 for 替換,反之亦然。

優化

// 原始循環
var j = 0;
while (j < items.length){
    process(items[j++]);
}
// 最小化屬性查找
var j = 0,
    count = items.length;
while (j < count){
    process(items[j++]);
}
// 最小化屬性查找和反序
var j = items.length;
while (j--){
    process(items[j]);
}
複製代碼

Do-While 循環

do-while 是第三種循環,它是 JavaScript 中惟一的後測試循環。由循環體和後測試條件組成:

var i = 0;
do {
    //循環體
} while (i++ < 10); 複製代碼

解析

在這種類型的循環中,循環體老是至少執行一次。而後評估測試後的條件,若是它是true,則執行另外一個循環週期。

優化

// 原始循環
var k = 0;
do {
    process(items[k++]);
} while (k < items.length);
// 最小化屬性查找
var k = 0,
    num = items.length;
do {
    process(items[k++]);
} while (k < num);
// 最小化屬性查找和反序
var k = items.length - 1;
do {
    process(items[k]);
} while (k--);
複製代碼

For-In 循環

最後一種是 for-in 循環。它有一個很是特殊的用途 —— 枚舉 JavaScript 對象的命名屬性。 它的語法以下:

for (var prop in object){
    //loop body
}
複製代碼

解析

它的名稱與 for 循環相似。可是工做方式徹底不一樣。而這種差別使它比另外三種循環慢得多,後者具備相同的性能特徵,因此爭論哪一個循環最快是沒有用的。

每次循環執行時,變量 prop 會獲得 object 的一個屬性。它將會不斷執行,直到返回全部屬性爲止。這些是對象自身的以及經過其原型鏈繼承的屬性。

注意事項

永遠不要用「 for-in 」來迭代數組成員

這種循環的每次迭代都會在實例或原型上進行屬性查找,這使得 for-in 循環比其它循環要慢得多。對於相同次數的迭代,可能會比其它循環慢七倍。

結論

  • forwhiledo-while 循環都有相似的性能特徵,所以沒有哪一種類型比其餘的更快或更慢。
  • 避免使用 for-in 循環,除非你須要對大量未知對象屬性進行迭代。
  • 提升循環性能的最佳方法是減小每次迭代完成的工做量並減小循環迭代次數

🔥 但願這對你有用,感謝閱讀! 🔥

資源

高性能 JavaScript - Nicholas C. Zakas

歡迎關注公衆號:前端先鋒,獲取更多前端乾貨!

相關文章
相關標籤/搜索