JavaScript 是 Web 開發領域的「常青樹」。無論是 JavaScript 框架(如 Node.js、React、Angular、Vue 等),或是原生 JavaScript,都擁有非常龐大的粉絲基礎。我們來談談現代 JavaScript 吧。循環一直是大多數程式語言的重要組成部分,而現代 JavaScript 為我們提供了許多迭代或循環值的方法。
但問題在於,我們是否真的知道哪種循環或迭代最適合我們的需求。 for
迴圈有很多變形,例如for
、for
(倒序)、for…of
、forEach
、 for…in
、for…await
。本文將圍繞這些展開討論。
了解哪一種 for 循環或迭代器適合我們的需求,防止我們犯下一些影響應用效能的低階錯誤。
答案其實是: for
(倒序)
最讓我感到驚訝的事情是,當我在本機電腦上進行測試之後,我不得不接受for
(倒序)是所有for
迴圈中最快的這一事實。下面我會舉個對一個包含超過一百萬項元素的陣列執行一次迴圈遍歷的例子。
宣告:console.time()
結果的準確度在很大程度上取決於我們執行測試的系統配置。你可以在此處對準確度作進一步了解。
const million = 1000000; const arr = Array(million); // 注:这是稀疏数组,应该为其指定内容,否则不同方式的循环对其的处理方式会不同: // const arr = [...Array(million)] console.time('⏳'); for (let i = arr.length; i > 0; i--) {} // for(倒序) :- 1.5ms for (let i = 0; i < arr.length; i++) {} // for :- 1.6ms arr.forEach(v => v) // foreach :- 2.1ms for (const v of arr) {} // for...of :- 11.7ms console.timeEnd('⏳');
造成這樣結果的原因很簡單,在程式碼中,正序和倒序的 for
迴圈幾乎花費一樣的時間,僅僅相差了 0.1 毫秒。原因是,for
(倒序)只需要計算一次起始變數let i = arr.length
,而在正序的for
迴圈中,它在每次變數增加後都會檢查條件i<arr.length>。這個細微的差別不是很重要,你可以忽略它。 (譯者註:在數據量小或對時間不敏感的代碼上,我們大可忽略它,但是根據譯者的測試,當數據量擴大,例如十億,千億等的數量級,差距就顯著提升,我們就需要考慮時間對應用程式效能的影響了。)</arr.length>
而forEach
是Array
原型的一個方法,與普通的for
迴圈相比,forEach
和for…of
需要花費更多的時間進行陣列迭代。 (譯者註:但值得注意的是,for…of
和forEach
都從物件中取得了數據,而原型並沒有,因此沒有可比性。)
1. For 迴圈(正序和倒序)
我想,也許大家都應該對這個基礎循環非常熟悉了。我們可以在任何我們需要的地方使用 for
循環,按照核定的次數運行一段程式碼。最基礎的 for
迴圈運行最迅速的,那我們每次都應該使用它,對嗎?並不然,效能不僅僅只是唯一尺度,程式碼可讀性往往更加重要,就讓我們選擇適合我們應用程式的變形即可。
2. forEach
#這個方法需要接受一個回呼函數作為輸入參數,遍歷數組的每一個元素,並執行我們的回調函數(以元素本身和它的索引(可選參數)作為參數賦予給回調函數)。 forEach
也允許在回呼函數中使用一個可選參數 this
。
const things = ['have', 'fun', 'coding']; const callbackFun = (item, idex) => { console.log(`${item} - ${index}`); } things.foreach(callbackFun); /* 输出 have - 0 fun - 1 coding - 2 */
要注意的是,如果我們要使用forEach
,我們不能使用JavaScript 的短路運算子(||、&&…),即不能在每個循環中跳過或結束循環。
3. for…of
for…of
##是在ES6(ECMAScript 6)中實現標準化的。它會對一個可迭代的物件(例如
array
、map、
const arr = [3, 5, 7]; const str = 'hello'; for (let i of arr) { console.log(i); // 输出 3, 5, 7 } for (let i of str) { console.log(i); // 输出 'h', 'e', 'l', 'l', 'o' }###要注意的是,請不要在生成器中使用 ###for…of###,即使 ###for…of### 迴圈提前終止。在退出循環後,生成器被關閉,並嘗試再次迭代,不會產生任何進一步的結果。 ############4. #########for### ###in############
for…in
会在对象的所有可枚举属性上迭代指定的变量。对于每个不同的属性,for…in
语句除返回数字索引外,还将返回用户定义的属性的名称。
因此,在遍历数组时最好使用带有数字索引的传统 for
循环。 因为 for…in
语句还会迭代除数组元素之外的用户定义属性,就算我们修改了数组对象(例如添加自定义属性或方法),依然如此。
const details = {firstName: 'john', lastName: 'Doe'}; let fullName = ''; for (let i in details) { fullName += details[i] + ' '; // fullName: john doe }
<span style="font-size: 16px;">for…of</span>
和 <span style="font-size: 16px;">for…in</span>
for…of
和 for…in
之间的主要区别是它们迭代的内容。for…in
循环遍历对象的属性,而 for…of
循环遍历可迭代对象的值。
let arr= [4, 5, 6]; for (let i in arr) { console.log(i); // '0', '1', '2' } for (let i of arr) { console.log(i); // '4', '5', '6' }
结论
for
最快,但可读性比较差foreach
比较快,能够控制内容for...of
比较慢,但香for...in
比较慢,没那么方便最后,给你一条明智的建议 —— 优先考虑可读性。尤其是当我们开发复杂的结构程序时,更需要这样做。当然,我们也应该专注于性能。尽量避免增添不必要的、多余的花哨代码,因为这有时可能对你的程序性能造成严重影响。祝你编码愉快。
译者注
在译者的实际测试中,发现:
英文原文地址:https://medium.com/javascript-in-plain-english/which-type-of-loop-is-fastest-in-javascript-ec834a0f21b9
原文作者:kushsavani
本文转载自:https://juejin.cn/post/6930973929452339213
译者:霜羽 Hoarfroster
更多编程相关知识,请访问:编程入门!!
以上是JavaScript中哪種類型的循環最快?幾種for迴圈對比的詳細內容。更多資訊請關注PHP中文網其他相關文章!