日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

譯者 | 劉汪洋

審校 | 重樓

概括:這篇文章介紹了 JAVAScript 中各種循環(huán)語句的特點(diǎn)和性能,以及如何根據(jù)不同的場(chǎng)景選擇合適的循環(huán)方式。文章通過一些實(shí)例和測(cè)試,給出了一些使用循環(huán)的最佳實(shí)踐,如避免不必要的計(jì)算、使用緩存變量、使用 break 和 continue 等。

介紹

循環(huán)是編程語言的基本組成部分,在 JavaScript 中也同樣不可或缺。JavaScript 循環(huán)是一種功能強(qiáng)大的編程工具,它讓開發(fā)者能夠遍歷數(shù)據(jù)集合,針對(duì)每個(gè)項(xiàng)目執(zhí)行特定操作,并根據(jù)具體條件作出決策。

然而,實(shí)現(xiàn)方式不當(dāng)可能導(dǎo)致負(fù)面問題。編寫錯(cuò)誤的循環(huán)不僅可能引發(fā)性能問題和編程錯(cuò)誤,還可能使代碼變得難以維護(hù)。
無論你是編程新手還是有豐富經(jīng)驗(yàn)的開發(fā)人員,編寫高效且合理的循環(huán)總是一項(xiàng)充滿挑戰(zhàn)的任務(wù)。

在本全面指南中,我們將詳細(xì)探討編寫 JavaScript 循環(huán)的最佳實(shí)踐,助你將代碼從新手水平提升至專家水平。我們將從最基本的部分開始,涵蓋如何選擇正確的循環(huán)類型和優(yōu)化循環(huán)性能等方面。
后面,我們還將深入探討更高級(jí)的主題,包括如何運(yùn)用函數(shù)式編程技巧,以及如何在處理異步循環(huán)時(shí)保持謹(jǐn)慎,以避免代碼運(yùn)行時(shí)出現(xiàn)不可預(yù)見的情況。

不論你是使用 數(shù)組、對(duì)象 還是其他數(shù)據(jù)結(jié)構(gòu),我們所分享的技巧和方法都將有助于你編寫干凈、簡(jiǎn)潔且無 bug 的循環(huán)代碼。
因此,如果你準(zhǔn)備深入了解 JavaScript 循環(huán)的精髓,那就做好準(zhǔn)備,讓我們共同探索吧!

選擇正確類型的循環(huán)

在 JavaScript 編程中,選擇合適的循環(huán)類型很關(guān)鍵。JavaScript 提供了幾種主要的循環(huán)類型,包括 for 循環(huán)、while 循環(huán)和do-while 循環(huán),每種類型都有其適用場(chǎng)景及優(yōu)缺點(diǎn)。

For 循環(huán)

For 循環(huán)是 JavaScript 中最常用的循環(huán)類型,特別適用于在已知循環(huán)次數(shù)的情況。
例如,要計(jì)算數(shù)字?jǐn)?shù)組的和:

let numbers = [1, 2, 3, 4, 5];
let sum = 0;
for (let i = 0; i < numbers.length; i++) {
  sum += numbers[i];
}
console.log(sum); // 輸出:15

在此示例中,for 循環(huán)遍歷數(shù)組的每個(gè)元素并累加其值。

While 循環(huán)

While 循環(huán)適用于重復(fù)執(zhí)行代碼塊直到滿足某條件的場(chǎng)景。
例如,生成大于 0.5 的隨機(jī)數(shù):

let randomNumber = Math.random();
while (randomNumber <= 0.5) {
  randomNumber = Math.random();
}
console.log(randomNumber); // 輸出:大于 0.5 的數(shù)字

此例中,while 循環(huán)不斷生成新的隨機(jī)數(shù),直到滿足條件。

Do-While 循環(huán)

Do-while 循環(huán)與while 循環(huán)相似,但無論初始條件如何,至少會(huì)執(zhí)行一次代碼塊。
例如,要求用戶輸入一個(gè)介于 1 和 10 之間的數(shù)字:

let number;
do {
  number = prompt('輸入一個(gè)介于 1 和 10 之間的數(shù)字:');
} while (number < 1 || number > 10);
console.log(number); // 輸出:介于 1 和 10 之間的數(shù)字

此例中,do-while 循環(huán)反復(fù)提示用戶輸入合法數(shù)字。
選擇合適的循環(huán)類型取決于具體需求和任務(wù)。如果已知執(zhí)行次數(shù),通常選擇 for 循環(huán);如果需要滿足某個(gè)條件才停止執(zhí)行,則 while 循環(huán)或 do-while 循環(huán)可能更合適。通過慎重選擇循環(huán)類型,可以使代碼執(zhí)行更高效、更易于理解。

循環(huán)控制語句的正確使用

選擇了合適的循環(huán)結(jié)構(gòu)后,你還需要深入了解如何在 JavaScript 中正確運(yùn)用兩種主要的循環(huán)控制語句:break 和 continue。
這兩種控制語句可以讓你更靈活地控制循環(huán)的執(zhí)行流程。當(dāng)滿足特定條件時(shí),break 語句用于完全終止循環(huán),而 continue 語句則用于跳過當(dāng)前迭代并進(jìn)入下一個(gè)迭代。
例如,設(shè)有一個(gè)數(shù)字?jǐn)?shù)組,你想通過 for 循環(huán)找到數(shù)組中的第一個(gè)偶數(shù)數(shù)字。一旦找到第一個(gè)偶數(shù),你可以使用 break 語句退出循環(huán):

const numbers = [1, 3, 2, 5, 4, 7, 6];
for (let i = 0; i < numbers.length; i++) {
  if (numbers[i] % 2 === 0) {
    console.log(`第一個(gè)偶數(shù)是 ${numbers[i]}`);
    break;
  }
}

在這個(gè)例子中,一旦找到第一個(gè)偶數(shù)(即 2),循環(huán)就會(huì)終止。如果沒有 break 語句,循環(huán)會(huì)繼續(xù)遍歷數(shù)組的其余部分。
相對(duì)于上述情況,如果你想在數(shù)組中打印所有的奇數(shù),并跳過所有偶數(shù),可以使用 continue 語句:

const numbers = [1, 3, 2, 5, 4, 7, 6];
for (let i = 0; i < numbers.length; i++) {
  if (numbers[i] % 2 === 0) {
    continue;
  }
  console.log(`奇數(shù):${numbers[i]}`);
}

在這個(gè)例子中,循環(huán)會(huì)跳過偶數(shù),僅打印奇數(shù)(即 1、3、5 和 7)。如果沒有 continue 語句,循環(huán)將會(huì)打印數(shù)組中的所有數(shù)字。
如今,我們已經(jīng)掌握了如何為特定任務(wù)選擇適當(dāng)?shù)难h(huán),以及何時(shí)使用 break 和 continue 語句。
下一步我們將探討的是編寫循環(huán)時(shí)需考慮的另一個(gè)重要方面:優(yōu)化循環(huán)性能。

優(yōu)化循環(huán)的性能

在日常編碼過程中,循環(huán)性能的優(yōu)化可能不會(huì)引起太多關(guān)注。但是當(dāng)面臨大數(shù)據(jù)處理時(shí),循環(huán)性能的提高就成為了關(guān)鍵任務(wù),因?yàn)樗鼤?huì)對(duì)整個(gè) JavaScript 代碼的性能產(chǎn)生決定性影響。因此,了解如何分析和增強(qiáng)循環(huán)性能變得至關(guān)重要。
以下是一些關(guān)于如何優(yōu)化循環(huán)性能的實(shí)用建議:

避免不必要的計(jì)算

一個(gè)提高循環(huán)性能的常見方法是減少不必要的計(jì)算。為了讓這一點(diǎn)更加明確,我們可以參考下述示例:
假設(shè)你正在對(duì)一個(gè)名為 array 的數(shù)組進(jìn)行迭代。在這種場(chǎng)景下,如果你使用 for 循環(huán)遍歷數(shù)組,每一次的迭代都會(huì)重新計(jì)算數(shù)組的 length 以確定是否應(yīng)繼續(xù)循環(huán)。
以下列代碼為例:

let arr = [1, 2, 3, 4, 5];
for (let i = 0; i < arr.length; i++) { 
  console.log(arr[i]); 
}

在每次迭代中,系統(tǒng)都會(huì)檢測(cè) i 是否小于數(shù)組長(zhǎng)度。但如果數(shù)組非常龐大,每次重新獲取長(zhǎng)度可能會(huì)成為性能瓶頸。注意:JavaScript 中的數(shù)組是特殊的對(duì)象,能夠容納各種數(shù)據(jù)類型。每個(gè)數(shù)組都帶有一個(gè) length 屬性,反映了其元素?cái)?shù)量,且會(huì)隨著元素的增減自動(dòng)更新。

為了改善性能,你可以在循環(huán)外部將數(shù)組的 length 存儲(chǔ)為一個(gè)變量:

let arr = [1, 2, 3, 4, 5];
let len = arr.length; // 緩存長(zhǎng)度
for (let i = 0; i < len; i++) { 
  console.log(arr[i]); 
}

這樣做可以避免在每次迭代中都訪問數(shù)組的 length 屬性,從而顯著提高代碼的運(yùn)行效率。對(duì)于處理大型數(shù)組,這個(gè)技巧可能特別有效。
注意:現(xiàn)代 JavaScript 引擎(如 V8)已經(jīng)高度優(yōu)化了循環(huán)。因此,有時(shí)緩存數(shù)組的長(zhǎng)度可能不會(huì)顯著提升性能。不過,作為良好編程實(shí)踐,特別是在處理大型數(shù)組或性能敏感代碼時(shí),這種技巧依然有價(jià)值。

高效循環(huán)的應(yīng)用

采用高效的循環(huán)結(jié)構(gòu)來提升循環(huán)性能是一項(xiàng)重要手段。
例如,在數(shù)組遍歷過程中,for 循環(huán)通常具有比 forEach 循環(huán)更高的執(zhí)行效率。
以下代碼片段可以讓我們深入理解這一觀點(diǎn):

let arr = [1, 2, 3, 4, 5]; // 使用 for 循環(huán)遍歷數(shù)組
for (let i = 0, len = arr.length; i < len; i++) { 
  console.log(arr[i]); 
}

在此例中,我們采用 for 循環(huán)來遍歷 arr 數(shù)組,但同樣的效果可以通過 forEach 循環(huán)實(shí)現(xiàn)。

那么,for 循環(huán)為何具有更高的執(zhí)行效率呢?

這個(gè)問題較為復(fù)雜,有許多細(xì)節(jié)值得深入探討。其中一個(gè)關(guān)鍵原因是,forEach 循環(huán)會(huì)為數(shù)組的每個(gè)元素創(chuàng)建一個(gè)新的函數(shù)作用域。

換言之,每個(gè)元素都會(huì)生成一個(gè)新的函數(shù),并在迭代結(jié)束后將其銷毀。

對(duì)于小型數(shù)組,這一過程影響不大。但是,當(dāng)處理大型數(shù)組時(shí),它可能會(huì)對(duì)循環(huán)的執(zhí)行速度產(chǎn)生負(fù)面影響。

與之相對(duì),for 循環(huán)只為整個(gè)循環(huán)過程創(chuàng)建一次函數(shù)作用域,因此僅需要?jiǎng)?chuàng)建并銷毀一個(gè)函數(shù)作用域。

另外,for 循環(huán)還支持使用 break 和 continue 來靈活控制循環(huán)的迭代過程,而 forEach 循環(huán)則無法實(shí)現(xiàn)這一功能。

正因如此,for 循環(huán)在數(shù)組遍歷時(shí)具備更高的優(yōu)化潛力。

DOM 操作的最小化

在循環(huán)過程中,減少對(duì)文檔對(duì)象模型(DOM)的操作至關(guān)重要,因?yàn)樵?JavaScript 中,與 DOM 的交互通常是一個(gè)耗時(shí)的過程。
每一次更改 DOM 都會(huì)讓瀏覽器重新布局和繪制頁(yè)面,可能降低應(yīng)用程序的執(zhí)行速度,特別是處理大量元素時(shí)。
例如:

// 低效的 DOM 操作 
for (let i = 0; i < 1000; i++) { 
  document.getElementById('myDiv').innerhtml += '<p>' + i + '</p>'; 
} 
// 更高效的 DOM 操作 
let output = ''; 
for (let i = 0; i < 1000; i++) { 
  output += '<p>' + i + '</p>'; 
} 
document.getElementById('myDiv').innerHTML = output;

在上述例子中,第一個(gè)循環(huán)效率較低,因?yàn)槊看蔚贾苯硬僮?DOM。每次迭代都會(huì)給 myDiv 元素的 innerHTML 屬性添加新段落,導(dǎo)致了 1000 次 DOM 操作。

與此相反,第二個(gè)循環(huán)的效率更高,原因在于它減少了對(duì) DOM 的直接操作。循環(huán)并不是在每次迭代時(shí)都更新 DOM,而是將 HTML 字符串累加到名為 output 的變量中。一旦循環(huán)完成,就使用 output 字符串僅一次更新 myDiv 元素的 innerHTML 屬性,從而實(shí)現(xiàn)了只進(jìn)行一次 DOM 操作,大大提高了效率。

規(guī)避常見錯(cuò)誤

在使用 JavaScript 編程時(shí),開發(fā)人員可能會(huì)遇到一些典型的錯(cuò)誤。以下要探討的這些錯(cuò)誤在實(shí)際編程中應(yīng)引起警覺,并積極規(guī)避。

循環(huán)內(nèi)部改動(dòng)循環(huán)變量

在循環(huán)內(nèi)部更改循環(huán)變量可能引發(fā)預(yù)期不到的效果或錯(cuò)誤。此做法通常并不合適。理想的方案是使用一個(gè)單獨(dú)的變量來存儲(chǔ)你希望更改的值。
例如,如下循環(huán):

for (let i = 0; i < 10; i++) { 
  console.log(i); i++; // 在循環(huán)內(nèi)修改 i 
}

上述代碼中,i 在循環(huán)中被修改,可能造成不在期望范圍的結(jié)果。相對(duì)地,你應(yīng)該像下面這樣使用一個(gè)單獨(dú)的變量來存儲(chǔ)你想要修改的值:

for (let i = 0; i < 10; i++) { 
  console.log(i); 
  let modifiedValue = i + 1; // 使用一個(gè)單獨(dú)的變量來修改 i 
}

忽略大括號(hào)的使用

雖然你可以在編寫循環(huán)時(shí)省略大括號(hào),但這通常并不推薦。缺少大括號(hào)可能復(fù)雜化代碼的閱讀和理解,甚至可能引發(fā)錯(cuò)誤或不預(yù)期的效果。
例如,如下循環(huán):

for (let i = 0; i < 10; i++) 
  console.log(i);

由于此循環(huán)未使用大括號(hào),可能使代碼的閱讀和理解變得困難,因此即使是單行語句,也最好始終使用大括號(hào):

for (let i = 0; i < 10; i++) { 
  console.log(i); 
}

避免無限循環(huán)

無限循環(huán)指的是永不終止的循環(huán)。當(dāng)退出條件設(shè)置不當(dāng),或永不滿足時(shí),就可能出現(xiàn)這種情況。無限循環(huán)不僅可能導(dǎo)致程序崩潰或掛起,還可能非常難以調(diào)試。
例如:
觀察下面的循環(huán),它沒有增加變量值,也未檢查是否超過某個(gè)閾值:

let count = 0; 
while (count < 10) { 
  console.log(count); 
}

由于 count 變量未曾增加,此代碼將觸發(fā)無限循環(huán)。
因此,你應(yīng)該時(shí)刻警惕無限循環(huán)的可能性。為了避免無限循環(huán),請(qǐng)確保設(shè)置了正確的退出條件,并對(duì)代碼進(jìn)行了充分測(cè)試。

“越界”錯(cuò)誤

在編程中,越界錯(cuò)誤是一種常見問題,發(fā)生在使用不正確的比較運(yùn)算符或未充分考慮循環(huán)變量初始值的情況下。這些錯(cuò)誤可能導(dǎo)致程序結(jié)果不準(zhǔn)確,甚至在某些情況下會(huì)觸發(fā)程序崩潰。
例如,假設(shè)你有一個(gè)包含 10 個(gè)元素的數(shù)組,你計(jì)劃遍歷它,并對(duì)每個(gè)元素執(zhí)行特定操作。
正確的循環(huán)編寫如下:

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 
for (let i = 0; i < arr.length; i++) { 
  console.log(arr[i]); 
}

該代碼將遍歷數(shù)組的全部 10 個(gè)元素,并將各個(gè)元素的值輸出到控制臺(tái)。但是,如果你誤用了比較運(yùn)算符,將 i< arr.length寫成 i<=arr.length會(huì)怎樣呢?

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 
for (let i = 0; i <= arr.length; i++) { 
  console.log(arr[i]); 
}

這段代碼將觸發(fā)一個(gè)越界錯(cuò)誤,因?yàn)楫?dāng)i等于 arr.length時(shí),將嘗試訪問一個(gè)不存在的元素。循環(huán)將執(zhí)行共計(jì)11 次而非 10 次,最后一次迭代將拋出錯(cuò)誤,因?yàn)?nbsp;arr[10] 的值為 undefined。為了防止越界錯(cuò)誤的發(fā)生,你應(yīng)仔細(xì)檢查循環(huán)條件、確保使用正確的比較運(yùn)算符,并充分考慮循環(huán)變量的初始值。通過避免這些常見錯(cuò)誤,你能夠確保循環(huán)的準(zhǔn)確執(zhí)行,從而降低程序中的錯(cuò)誤或崩潰風(fēng)險(xiǎn)。同時(shí),在執(zhí)行代碼之前,仔細(xì)審查潛在錯(cuò)誤始終是明智的做法。

在適當(dāng)場(chǎng)合,選擇遞歸

在程序設(shè)計(jì)中,遞歸經(jīng)常被視為一種優(yōu)雅的解決方案。
遞歸特別適用于處理層級(jí)數(shù)量未知或不固定的分層數(shù)據(jù)結(jié)構(gòu),如樹形結(jié)構(gòu)或嵌套數(shù)組。
與傳統(tǒng)的嵌套循環(huán)相比,當(dāng)處理具有未知深度的結(jié)構(gòu)時(shí),遞歸能使代碼更整潔、易讀。
警告:使用遞歸時(shí)需謹(jǐn)慎,確保遞歸有明確的終止條件,避免發(fā)生無限遞歸和棧溢出錯(cuò)誤。
例如,考慮以下情景:
假設(shè)你擁有一個(gè)包含嵌套數(shù)字的數(shù)組結(jié)構(gòu),你的任務(wù)是找到數(shù)組中所有數(shù)字(包括嵌套的數(shù)字)的總和。在此情景下,遞歸可以被優(yōu)雅地應(yīng)用。下面是一個(gè)通過遞歸來求嵌套數(shù)組總和的示例代碼:

const nestedArray = [[1, 2, [3]], 4]; 
function sumArray(arr) { 
  let sum = 0; 
  for (let i = 0; i < arr.length; i++) { 
    if (Array.isArray(arr[i])) { 
      // 如果當(dāng)前元素是數(shù)組,則遞歸處理
      sum += sumArray(arr[i]); 
    } else { 
      // 如果當(dāng)前元素是數(shù)字,則加入總和
      sum += arr[i]; 
    } 
  } 
  return sum; 
} 
console.log(sumArray(nestedArray)); // 輸出:10

此代碼利用遞歸深入遍歷嵌套數(shù)組 nestedArray。它可以計(jì)算所有數(shù)字的總和,而不受嵌套深度的限制。

遞歸函數(shù)允許自身反復(fù)調(diào)用,直到達(dá)到最底層的嵌套結(jié)構(gòu),并返回一個(gè)可用于計(jì)算最終總和的值。

通過檢查每個(gè)元素是否為數(shù)組,該函數(shù)遞歸處理數(shù)組元素,直到達(dá)到最深的嵌套層級(jí),即數(shù)字。

然后,函數(shù)將該數(shù)字返回到上一遞歸層。這樣便于計(jì)算當(dāng)前層級(jí)所有元素的總和。

通過這種方式,遞歸提供了一種靈活而優(yōu)雅的方法,用于處理未知或不固定層級(jí)結(jié)構(gòu)的問題。

結(jié)論

JavaScript 循環(huán)非常重要,但要精通使用它可能有一定的難度。遵循以上最佳實(shí)踐,你將能夠編寫更高效、更合理的循環(huán)代碼,進(jìn)而提升整體的編程水準(zhǔn)。
要選擇合適的循環(huán)類型,并準(zhǔn)確地使用循環(huán)控制語句來優(yōu)化循環(huán)性能,避免常見的錯(cuò)誤。同時(shí),在適宜的場(chǎng)景下,你可以考慮遞歸的使用。只要掌握這些技巧,你就能大幅增強(qiáng)自己在 JavaScript 循環(huán)方面的專業(yè)技能。
因此,如果你投入時(shí)間來評(píng)估和優(yōu)化循環(huán)代碼,你的代碼性能將得到顯著提升。

譯者介紹

劉汪洋,51CTO社區(qū)編輯,昵稱:明明如月,一個(gè)擁有 5 年開發(fā)經(jīng)驗(yàn)的某大廠高級(jí) Java 工程師,擁有多個(gè)主流技術(shù)博客平臺(tái)博客專家稱號(hào)。

原文標(biāo)題:JavaScript Loop: The Best Practices to Have the Optimal Performance,作者:robiulhr

分享到:
標(biāo)簽:JavaScript
用戶無頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定