在本文中,我想概述一下標準的 for 循環和 forEach() 方法背后的區別,并對它們各自帶來的一些好處進行評論。
作為免責聲明,請不要把標題當真。我寫這篇文章的目的是為了讓讀者了解缺點,并提供一些關于什么時候可以或不可以使用 forEach() 的見解,僅此而已。
forEach如何工作
forEach 方法接受回調函數作為輸入,對于要迭代的數組中的每個元素,將執行此回調函數。應該注意的是,回調函數可以接受一些可選參數。它們包括傳遞給函數的當前值,當前值的相應索引。forEach 函數還提供了一個可選的參數,用于在你的回調函數中定義。
考慮以下代碼:
相應的輸出為:
corgis - 0
are - 1
cool - 2
短路
如果您不知道什么是短路,它指的是我們提前終止或跳過循環的一個迭代。當我們在使用 forEach() 的時候,沒有辦法利用短路,在我們的循環的所有情況下,我們將忍受與數組大小有關的線性運行時間。
我為什么要關心這個?想象一下,我們有10億個元素的未排序數組,而我們想找到某個元素。假設我們非常幸運,并在循環的第一次迭代中找到了這個元素。實際上,我們希望盡早返回,因為我們已經找到了我們想要的東西,但是在實現 forEach() 的方式中,我們總是會遍歷剩下的元素。對于此類問題,我們可能會使用 .findIndex() 方法。
性能
在 forEach() 方法中,由于我們在每次迭代時都要調用一個回調函數,所以我們產生了一個額外的作用域開銷,與原生的 for 循環相比會導致速度變慢。
與傳統的 for 循環相比,我們有一個初始化語句、一個在每次迭代中求值的條件語句和一個在循環體遞增后的執行階段。相對于 forEach() 方法,我們必須在每次迭代時創建額外的函數調用,它的成本更低。
為了測試性能,我創建了一個計時器腳本,該腳本在初始化數組后跟蹤執行時間。這兩個循環在其體內都執行了一個簡單的 O(1) 操作:
可讀性
在開發軟件時,創建可維護和可讀的代碼應該是頭等大事。我認為在代碼中繼續使用 forEach() 是為了提高可讀性。隨著方法鏈幾乎成為JAVAScript中數組的第二天性,使用 forEach() 循環來運行數組,而不是 for 循環,這樣讀起來會更好。
還應該注意的是,像上面的例子中的輸入尺寸非常大的情況,往往不太可能出現。在合理的輸入大小下,這兩個回路的性能相對相同。
你是否愿意以犧牲可讀性為代價,以更快的速度執行幾毫秒的功能?
如果對你有所啟發和幫助,可以點個關注、收藏、轉發,也可以留言討論,這是對作者的最大鼓勵。
作者簡介:Web前端工程師,全棧開發工程師、持續學習者。