區別:1、forEach是一個迭代器,是負責遍歷(Array Set Map)可迭代物件的;而for是一種循環機制,只是能透過它遍歷出數組。 2.for循環中會用到一些中斷行為,對於優化數組遍歷查找是很好的,但由於forEach屬於迭代器,只能按序依次遍歷完成,所以不支援中斷行為。 3.forEach的循環起點只能為0,且不能進行人為幹預;而for循環不同,可以人為控制循環起點。
本教學操作環境:windows7系統、ECMAScript 6版、Dell G3電腦。
for迴圈和forEach本質差異
#for
迴圈是js提出時就有的迴圈方法。
forEach
是ES5提出的,掛載在可迭代物件原型上的方法,例如Array
Set
Map
。
forEach
是一個迭代器,負責遍歷可迭代物件。
那麼遍歷,迭代,可迭代物件分別是什麼呢。
遍歷:指的對資料結構的每一個成員進行有規律的且為一次存取的行為。
迭代:迭代是遞歸的特殊形式,是迭代器提供的一種方法,預設是依照一定順序逐一存取資料結構成員。迭代也是一種遍歷行為。
可迭代物件:ES6中引入了
iterable
類型,Array
Set
Map
String
arguments
NodeList
都屬於iterable
,他們特質就是都擁有[Symbol.iterator]
方法,包含他的物件被認為是可迭代的iterable
。
forEach
其實是一個迭代器,他與for
迴圈本質上的差別是forEach
是負責遍歷(Array
Set
Map
)可迭代物件的,而for
迴圈是一種循環機制,只是能透過它遍歷出數組。
什麼是迭代器,當它被呼叫時就會產生一個迭代器物件(Iterator Object),它有一個.next()
方法,每次呼叫傳回一個物件{value:value,done:Boolean}
,value
傳回的是yield
後的回傳值,當yield
結束,done
變成true
,透過不斷呼叫並依序的迭代存取內部的值。
迭代器是一種特殊物件。 ES6規範中它的標誌是傳回物件的 next()
方法,迭代行為判斷在 done
之中。在不暴露內部表示的情況下,迭代器實現了遍歷。看程式碼
let arr = [1, 2, 3, 4] // 可迭代对象 let iterator = arr[Symbol.iterator]() // 调用 Symbol.iterator 后生成了迭代器对象 console.log(iterator.next()); // {value: 1, done: false} 访问迭代器对象的next方法 console.log(iterator.next()); // {value: 2, done: false} console.log(iterator.next()); // {value: 3, done: false} console.log(iterator.next()); // {value: 4, done: false} console.log(iterator.next()); // {value: undefined, done: true}
我們看到了。只要是可迭代對象,呼叫內部的Symbol.iterator
都會提供一個迭代器,並根據迭代器返回的next
方法來存取內部,這也是for.. .of
的實作原理。
let arr = [1, 2, 3, 4] for (const item of arr) { console.log(item); // 1 2 3 4 }
把呼叫next
方法傳回物件的value
值並儲存在item
中,直到value
為undefined
跳出循環,所有可迭代物件可供for...of
消費。再來看看其他可迭代物件:
function num(params) { console.log(arguments); // Arguments(6) [1, 2, 3, 4, callee: ƒ, Symbol(Symbol.iterator): ƒ] let iterator = arguments[Symbol.iterator]() console.log(iterator.next()); // {value: 1, done: false} console.log(iterator.next()); // {value: 2, done: false} console.log(iterator.next()); // {value: 3, done: false} console.log(iterator.next()); // {value: 4, done: false} console.log(iterator.next()); // {value: undefined, done: true} } num(1, 2, 3, 4) let set = new Set('1234') set.forEach(item => { console.log(item); // 1 2 3 4 }) let iterator = set[Symbol.iterator]() console.log(iterator.next()); // {value: 1, done: false} console.log(iterator.next()); // {value: 2, done: false} console.log(iterator.next()); // {value: 3, done: false} console.log(iterator.next()); // {value: 4, done: false} console.log(iterator.next()); // {value: undefined, done: true}
所以可迭代物件中的Symbol.iterator
屬性被呼叫時都能產生迭代器,而forEach
也是生成一個迭代器,在內部的回呼函數中傳遞出每個元素的值
<span style="font-size: 20px;">#for</span>
##循環和<span style="font-size: 20px;"></span>#forEach
的語法差異
-
的參數。forEach
-
的中斷。forEach
-
刪除自身元素,index無法重設。forEach
-
迴圈可以控制迴圈起點。for
forEach 的參數
我們真正了解
forEach
arr.forEach((self,index,arr) =>{},this)
self:
陣列目前遍歷的元素,預設從左往右依序取得陣列元素。index:
陣列目前元素的索引,第一個元素索引為0,依序類別推。arr:
目前遍歷的陣列。this:
回呼函數中this指向。let arr = [1, 2, 3, 4]; arr.forEach(function (self, index, arr) { console.log(`当前元素为${self}索引为${index},属于数组${arr}`); }, person)
我們可以利用
arr 實作陣列去重:###let arr1 = [1, 2, 1, 3, 1]; let arr2 = []; arr1.forEach(function (self, index, arr) { arr.indexOf(self) === index ? arr2.push(self) : null; }); console.log(arr2); // [1,2,3]
forEach
的中断
在js中有break
return
continue
对函数进行中断或跳出循环的操作,我们在 for
循环中会用到一些中断行为,对于优化数组遍历查找是很好的,但由于forEach
属于迭代器,只能按序依次遍历完成,所以不支持上述的中断行为。
let arr = [1, 2, 3, 4], i = 0, length = arr.length; for (; i { console.log(self); if (self === 2) { break; //报错 }; }); arr.forEach((self,index) => { console.log(self); if (self === 2) { continue; //报错 }; });
如果我一定要在 forEach
中跳出循环呢?其实是有办法的,借助try/catch
:
try { var arr = [1, 2, 3, 4]; arr.forEach(function (item, index) { //跳出条件 if (item === 3) { throw new Error("LoopTerminates"); } //do something console.log(item); }); } catch (e) { if (e.message !== "LoopTerminates") throw e; };
若遇到 return
并不会报错,但是不会生效
let arr = [1, 2, 3, 4]; function find(array, num) { array.forEach((self, index) => { if (self === num) { return index; }; }); }; let index = find(arr, 2);// undefined
forEach
删除自身元素,index不可被重置
在 forEach
中我们无法控制 index
的值,它只会无脑的自增直至大于数组的 length
跳出循环。所以也无法删除自身进行index
重置,先看一个简单例子:
let arr = [1,2,3,4] arr.forEach((item, index) => { console.log(item); // 1 2 3 4 index++; });
index
不会随着函数体内部对它的增减而发生变化。在实际开发中,遍历数组同时删除某项的操作十分常见,在使用forEach
删除时要注意。
for
循环可以控制循环起点
如上文提到的 forEach
的循环起点只能为0不能进行人为干预,而for
循环不同:
let arr = [1, 2, 3, 4], i = 1, length = arr.length; for (; i <p>那之前的数组遍历并删除滋生的操作就可以写成</p><pre class="brush:php;toolbar:false">let arr = [1, 2, 1], i = 0, length = arr.length; for (; i index !== 1); console.log(arr1) // [2]
<span style="font-size: 18px;">for</span>
循环和<span style="font-size: 18px;">forEach</span>
的性能区别
在性能对比方面我们加入一个 map
迭代器,它与 filter
一样都是生成新数组。
对比 for
forEach
map
的性能在浏览器环境中都是什么样的:
性能比较:for > forEach > map 在chrome 62 和 Node.js v9.1.0环境下:for
循环比 forEach
快1倍,forEach
比 map
快20%左右。
原因分析for
:for循环没有额外的函数调用栈和上下文,所以它的实现最为简单。
forEach
:对于forEach来说,它的函数签名中包含了参数和上下文,所以性能会低于 for
循环。
map
:map
最慢的原因是因为 map
会返回一个新的数组,数组的创建和赋值会导致分配内存空间,因此会带来较大的性能开销。
如果将map
嵌套在一个循环中,便会带来更多不必要的内存消耗。
当大家使用迭代器遍历一个数组时,如果不需要返回一个新数组却使用 map
是违背设计初衷的。
【相关推荐:javascript视频教程、编程视频】
以上是es6中for和foreach的差別是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

React受歡迎的原因包括其性能優化、組件復用和豐富的生態系統。 1.性能優化通過虛擬DOM和diffing機制實現高效更新。 2.組件復用通過可複用組件減少重複代碼。 3.豐富的生態系統和單向數據流增強了開發體驗。

React是構建動態和交互式用戶界面的首選工具。 1)組件化與JSX使UI拆分和復用變得簡單。 2)狀態管理通過useState鉤子實現,觸發UI更新。 3)事件處理機制響應用戶交互,提升用戶體驗。

React是前端框架,用於構建用戶界面;後端框架用於構建服務器端應用程序。 React提供組件化和高效的UI更新,後端框架提供完整的後端服務解決方案。選擇技術棧時需考慮項目需求、團隊技能和可擴展性。

HTML和React的關係是前端開發的核心,它們共同構建現代Web應用的用戶界面。 1)HTML定義內容結構和語義,React通過組件化構建動態界面。 2)React組件使用JSX語法嵌入HTML,實現智能渲染。 3)組件生命週期管理HTML渲染,根據狀態和屬性動態更新。 4)使用組件優化HTML結構,提高可維護性。 5)性能優化包括避免不必要渲染,使用key屬性,保持組件單一職責。

React是構建交互式前端體驗的首選工具。 1)React通過組件化和虛擬DOM簡化UI開發。 2)組件分為函數組件和類組件,函數組件更簡潔,類組件提供更多生命週期方法。 3)React的工作原理依賴虛擬DOM和調和算法,提高性能。 4)狀態管理使用useState或this.state,生命週期方法如componentDidMount用於特定邏輯。 5)基本用法包括創建組件和管理狀態,高級用法涉及自定義鉤子和性能優化。 6)常見錯誤包括狀態更新不當和性能問題,調試技巧包括使用ReactDevTools和優

React是一個用於構建用戶界面的JavaScript庫,其核心是組件化和狀態管理。 1)通過組件化和狀態管理簡化UI開發。 2)工作原理包括調和和渲染,優化可通過React.memo和useMemo實現。 3)基本用法是創建並渲染組件,高級用法包括使用Hooks和ContextAPI。 4)常見錯誤如狀態更新不當,可使用ReactDevTools調試。 5)性能優化包括使用React.memo、虛擬化列表和CodeSplitting,保持代碼可讀性和可維護性是最佳實踐。

React通過JSX與HTML結合,提升用戶體驗。 1)JSX嵌入HTML,使開發更直觀。 2)虛擬DOM機制優化性能,減少DOM操作。 3)組件化管理UI,提高可維護性。 4)狀態管理和事件處理增強交互性。

React組件可以通過函數或類定義,封裝UI邏輯並通過props接受輸入數據。 1)定義組件:使用函數或類,返回React元素。 2)渲染組件:React調用render方法或執行函數組件。 3)復用組件:通過props傳遞數據,構建複雜UI。組件的生命週期方法允許在不同階段執行邏輯,提升開發效率和代碼可維護性。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

Atom編輯器mac版下載
最受歡迎的的開源編輯器

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。