精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

面試官:有了 for 循環 為什么還要 forEach ?

開發 前端
js中那么多循環,for for...in for...of forEach,有些循環感覺上是大同小異今天我們討論下for循環和forEach的差異。

[[441197]]

 js中那么多循環,for for...in for...of forEach,有些循環感覺上是大同小異今天我們討論下for循環和forEach的差異。我們從幾個維度展開討論:

  •  for循環和forEach的本質區別。
  •  for循環和forEach的語法區別。
  •  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 循環是一種循環機制,只是能通過它遍歷出數組。

再來聊聊究竟什么是迭代器,還記得之前提到的 Generator 生成器,當它被調用時就會生成一個迭代器對象(Iterator Object),它有一個 .next()方法,每次調用返回一個對象{value:value,done:Boolean},value返回的是 yield 后的返回值,當 yield 結束,done 變為 true,通過不斷調用并依次的迭代訪問內部的值。

迭代器是一種特殊對象。ES6規范中它的標志是返回對象的 next() 方法,迭代行為判斷在 done 之中。在不暴露內部表示的情況下,迭代器實現了遍歷。看代碼 

  1. let arr = [1, 2, 3, 4]  // 可迭代對象  
  2. let iterator = arr[Symbol.iterator]()  // 調用 Symbol.iterator 后生成了迭代器對象  
  3. console.log(iterator.next()); // {value: 1, done: false}  訪問迭代器對象的next方法  
  4. console.log(iterator.next()); // {value: 2, done: false}  
  5. console.log(iterator.next()); // {value: 3, done: false}  
  6. console.log(iterator.next()); // {value: 4, done: false}  
  7. console.log(iterator.next()); // {value: undefined, done: true} 

我們看到了。只要是可迭代對象,調用內部的 Symbol.iterator 都會提供一個迭代器,并根據迭代器返回的next 方法來訪問內部,這也是 for...of 的實現原理。 

  1. let arr = [1, 2, 3, 4]  
  2. for (const item of arr) {  
  3.     console.log(item); // 1 2 3 4  
  4.  

把調用 next 方法返回對象的 value 值并保存在 item 中,直到 value 為 undefined 跳出循環,所有可迭代對象可供for...of消費。再來看看其他可迭代對象: 

  1. function num(params) {  
  2.     console.log(arguments); // Arguments(6) [1, 2, 3, 4, callee: ƒ, Symbol(Symbol.iterator): ƒ]  
  3.     let iterator = arguments[Symbol.iterator]()  
  4.     console.log(iterator.next()); // {value: 1, done: false}  
  5.     console.log(iterator.next()); // {value: 2, done: false}  
  6.     console.log(iterator.next()); // {value: 3, done: false}  
  7.     console.log(iterator.next()); // {value: 4, done: false}  
  8.     console.log(iterator.next()); // {value: undefined, done: true}  
  9.  
  10. num(1, 2, 3, 4)  
  11. let set = new Set('1234')  
  12. set.forEach(item => {  
  13.     console.log(item); // 1 2 3 4  
  14. })  
  15. let iterator = set[Symbol.iterator]()  
  16. console.log(iterator.next()); // {value: 1, done: false}  
  17. console.log(iterator.next()); // {value: 2, done: false}  
  18. console.log(iterator.next()); // {value: 3, done: false} 
  19. console.log(iterator.next()); // {value: 4, done: false}  
  20. console.log(iterator.next()); // {value: undefined, done: true} 

所以我們也能很直觀的看到可迭代對象中的 Symbol.iterator 屬性被調用時都能生成迭代器,而 forEach 也是生成一個迭代器,在內部的回調函數中傳遞出每個元素的值。

(感興趣的同學可以搜下 forEach 源碼, Array Set Map 實例上都掛載著 forEach ,但網上的答案大多數是通過 length 判斷長度, 利用for循環機制實現的。但在 Set Map 上使用會報錯,所以我認為是調用的迭代器,不斷調用 next,傳參到回調函數。由于網上沒查到答案也不妄下斷言了,有答案的人可以評論區留言)

for循環和forEach的語法區別

了解了本質區別,在應用過程中,他們到底有什么語法區別呢?

  1. forEach 的參數。
  2.  forEach 的中斷。
  3.  forEach 刪除自身元素,index不可被重置。
  4.  for 循環可以控制循環起點。

forEach 的參數

我們真正了解 forEach 的完整傳參內容嗎?它大概是這樣: 

  1. arr.forEach((self,index,arr) =>{},this) 

self: 數組當前遍歷的元素,默認從左往右依次獲取數組元素。

index: 數組當前元素的索引,第一個元素索引為0,依次類推。

arr: 當前遍歷的數組。

this: 回調函數中this指向。 

  1. let arr = [1, 2, 3, 4];  
  2. let person = {  
  3.     name: '技術直男星辰'  
  4. };  
  5. arr.forEach(function (self, index, arr) {  
  6.     console.log(`當前元素為${self}索引為${index},屬于數組${arr}`);  
  7.     console.log(this.name+='真帥');  
  8. }, person) 

我們可以利用 arr 實現數組去重: 

  1. let arr1 = [1, 2, 1, 3, 1];  
  2. let arr2 = [];  
  3. arr1.forEach(function (self, index, arr) {  
  4.     arr.indexOf(self) === index ? arr2.push(self) : null;  
  5. });  
  6. console.log(arr2);   // [1,2,3] 

forEach 的中斷

在js中有break return continue 對函數進行中斷或跳出循環的操作,我們在 for循環中會用到一些中斷行為,對于優化數組遍歷查找是很好的,但由于forEach屬于迭代器,只能按序依次遍歷完成,所以不支持上述的中斷行為。 

  1. let arr = [1, 2, 3, 4],  
  2.     i = 0 
  3.     length = arr.length;  
  4. for (; i < length; i++) {  
  5.     console.log(arr[i]); //1,2  
  6.     if (arr[i] === 2) {  
  7.         break;  
  8.     };  
  9. };  
  10. arr.forEach((self,index) => {  
  11.     console.log(self);  
  12.     if (self === 2) {  
  13.         break; //報錯  
  14.     };  
  15. });  
  16. arr.forEach((self,index) => {  
  17.     console.log(self);  
  18.     if (self === 2) {  
  19.         continue; //報錯  
  20.     };  
  21. }); 

如果我一定要在 forEach 中跳出循環呢?其實是有辦法的,借助try/catch: 

  1. try {  
  2.     var arr = [1, 2, 3, 4];  
  3.     arr.forEach(function (item, index) {  
  4.         //跳出條件  
  5.         if (item === 3) {  
  6.             throw new Error("LoopTerminates");  
  7.         }  
  8.         //do something  
  9.         console.log(item);  
  10.     });  
  11. } catch (e) {  
  12.     if (e.message !== "LoopTerminates") throw e;  
  13. }; 

若遇到 return 并不會報錯,但是不會生效 

  1. let arr = [1, 2, 3, 4];  
  2. function find(array, num) {     
  3.     array.forEach((self, index) => {     
  4.          if (self === num) {    
  5.              return index;      
  6.          };    
  7.      });  
  8. }; 
  9.  let index = find(arr, 2);// undefined 

forEach 刪除自身元素,index不可被重置

在 forEach 中我們無法控制 index 的值,它只會無腦的自增直至大于數組的 length 跳出循環。所以也無法刪除自身進行index重置,先看一個簡單例子: 

  1. let arr = [1,2,3,4]  
  2. arr.forEach((item, index) => {    
  3.     console.log(item); // 1 2 3 4   
  4.     index++;  
  5. }); 

index不會隨著函數體內部對它的增減而發生變化。在實際開發中,遍歷數組同時刪除某項的操作十分常見,在使用forEach刪除時要注意。

for 循環可以控制循環起點

如上文提到的 forEach 的循環起點只能為0不能進行人為干預,而for循環不同: 

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

那之前的數組遍歷并刪除滋生的操作就可以寫成 

  1. let arr = [1, 2, 1],  
  2.     i = 0 
  3.     length = arr.length;  
  4. for (; i < length; i++) {  
  5.     // 刪除數組中所有的1  
  6.     if (arr[i] === 1) {  
  7.         arr.splice(i, 1);  
  8.         //重置i,否則i會跳一位  
  9.         i--;  
  10.     };  
  11. };  
  12. console.log(arr); // [2]  
  13. //等價于  
  14. var arrarr1 = arr.filter(index => index !== 1);  
  15. console.log(arr1) // [2] 

for循環和forEach的性能區別

在性能對比方面我們加入一個 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 是違背設計初衷的。在我前端合作開發時見過很多人只是為了遍歷數組而用 map 的: 

  1. let data = [];  
  2. let data2 = [1,2,3];  
  3. data2.map(item=>data.push(item)); 

寫在最后:這是面試遇到的一個問題,當時只知道語法區別。并沒有從可迭代對象,迭代器,生成器和性能方面,多角度進一步區分兩者的異同,也希望能把一個簡單的問題從多角度展開細講,讓大家正在搞懂搞透徹。   

 

責任編輯:龐桂玉 來源: 前端大全
相關推薦

2025-11-10 03:00:00

2022-06-07 08:39:35

RPCHTTP

2022-07-06 13:48:24

RedisSentinel機制

2020-11-25 09:36:17

HTTPRPC遠程

2024-07-11 10:41:07

HTTPSHTTP文本傳輸協議

2019-08-05 14:23:43

DockerKubernetes容器

2023-08-11 17:13:39

JavaScrip

2023-12-06 09:10:28

JWT微服務

2021-02-19 10:02:57

HTTPSJava安全

2020-10-24 15:50:54

Java值傳遞代碼

2021-01-21 07:53:29

面試官Promis打印e

2025-09-24 17:05:02

2023-12-11 12:03:14

Python工具元組

2023-01-12 09:01:01

MongoDBMySQL

2023-09-04 08:28:34

JavaScripforEach 循環

2025-04-01 00:00:00

項目CRUD單例模式

2025-08-04 08:05:28

2024-04-16 08:26:18

IP地址MAC地址

2022-09-13 08:44:02

IP網絡MAC地址

2023-12-20 14:35:37

Java虛擬線程
點贊
收藏

51CTO技術棧公眾號

午夜精品久久17c| 欧美一区欧美二区| 久久国产精品-国产精品| 欧美日韩一级黄色片| 精品国内自产拍在线观看视频 | 成人精品动漫| 亚洲蜜桃精久久久久久久| 亚洲va久久久噜噜噜久久天堂| 青青草手机视频在线观看| 欧美在线关看| 69p69国产精品| 国产精品网站免费| 老司机在线看片网av| 99久久777色| 成人黄色大片在线免费观看| 日本一区二区欧美| 97人人精品| 亚洲国产天堂久久综合| 男女啪啪网站视频| 国产网红女主播精品视频| 欧美激情中文不卡| 国产丝袜不卡| 国产日韩欧美一区二区东京热| 亚洲一区日韩| 欧美激情网友自拍| 三级黄色录像视频| 久操国产精品| 亚洲精品国精品久久99热| 九九久久久久久| 成人交换视频| 日本精品视频一区二区| 精品丰满人妻无套内射| 精品欧美色视频网站在线观看| 久久久精品综合| 国内视频一区| 成人午夜视频一区二区播放| 久久er精品视频| 国产精品旅馆在线| 午夜婷婷在线观看| 一区二区久久| 97久久精品国产| 黄页网站免费观看| 亚洲欧美伊人| 久久视频在线免费观看| 亚洲午夜精品久久久久久高潮| 青青久久av| 精品国产3级a| www.四虎在线| 精品福利网址导航| 精品福利视频一区二区三区| 久久久无码人妻精品无码| 疯狂欧洲av久久成人av电影| 欧美日韩一级黄| 蜜桃免费在线视频| aaaa欧美| 欧美日韩电影在线播放| 依人在线免费视频| 少妇精品视频在线观看| 精品视频一区三区九区| 国产精品一区二区小说| 欧美一级免费| 欧美一区二区黄色| 亚洲性图第一页| 久本草在线中文字幕亚洲| 亚洲第一区中文字幕| 黑森林av导航| 免费看久久久| 亚洲欧美日韩网| 亚欧精品视频一区二区三区| 99精品网站| 欧美精品日韩www.p站| 欧美精品99久久久| 亚洲久久一区二区| 国产精品第三页| 亚洲一级视频在线观看| 国产中文一区二区三区| caoporen国产精品| 天堂中文资源在线观看| 91美女在线视频| 亚洲精品一区二区三区樱花| 国产原创视频在线观看| 亚洲国产一区视频| a√天堂在线观看| 国产资源一区| 精品少妇一区二区三区在线播放 | 欧美日韩亚洲一| 欧美国产日韩电影| 欧美一区二区人人喊爽| 国模私拍在线观看| 欧美特黄一级大片| 欧美成人精品h版在线观看| 国产女同在线观看| 蜜桃av一区二区| 国产高清精品一区二区三区| 美州a亚洲一视本频v色道| 自拍偷自拍亚洲精品播放| 国产成人永久免费视频| 偷拍精品精品一区二区三区| 538prom精品视频线放| 中文字幕乱码一区| 日韩理论电影| 8050国产精品久久久久久| 在线观看国产成人| 不卡的av在线播放| 国产又大又长又粗又黄| 涩涩视频在线| 日韩欧美一级片| 精品日韩在线视频| 亚洲理论在线| 成人精品一区二区三区电影免费| 色欲av永久无码精品无码蜜桃| 中文字幕av一区二区三区高 | 欧美污视频久久久| 中文在线免费| 欧美午夜免费电影| www.日本高清| 天堂网在线观看国产精品| 91精品国产高清| www久久久com| 中文字幕亚洲成人| 青青草av网站| 午夜精品福利影院| 欧美激情极品视频| 国产精品视频一区二区三区,| 久久夜色精品国产欧美乱极品| 美女av免费观看| 9999在线精品视频| 宅男66日本亚洲欧美视频| 亚洲AV无码成人精品区东京热| 国产成人8x视频一区二区| 免费看av软件| 日韩欧乱色一区二区三区在线| 亚洲丝袜在线视频| 综合激情网五月| 99精品一区二区| 免费人成在线观看视频播放| 国产一区二区| 久久综合免费视频影院| 一级片在线免费观看视频| 国产亚洲精品超碰| 免费黄色特级片| 亚洲免费专区| 日韩美女av在线免费观看| 亚洲 小说区 图片区 都市| 亚洲综合色区另类av| 国产精品二区视频| 国内精品久久久久久久影视蜜臀| 91老司机精品视频| 黄网页在线观看| 91精品国产全国免费观看| 欧美肥妇bbwbbw| 精品一区二区精品| 国产成人精品免费看在线播放| 亚洲免费一区| 色综合色综合久久综合频道88| 国产情侣自拍小视频| 亚洲另类春色国产| 丰满饥渴老女人hd| 99精品视频免费观看| 精品国产第一页| 色资源二区在线视频| 亚洲丝袜在线视频| 国产精品区在线观看| 亚洲精品日韩一| av不卡中文字幕| 国产精品视频| 亚洲ai欧洲av| 精品国产三区在线| 91精品国产91久久久久久| 日本a一级在线免费播放| 在线视频国内一区二区| 午夜国产福利视频| 国产成人在线免费| www.爱色av.com| 日本一区二区在线看| 国产精品视频自拍| 婷婷av在线| 亚洲精品一区久久久久久| 欧美另类高清videos的特点| 中文字幕亚洲不卡| 日本少妇毛茸茸| 美女免费视频一区| 妺妺窝人体色www看人体| 岳的好大精品一区二区三区| 国产精品影院在线观看| 污视频在线看网站| 亚洲天堂男人天堂女人天堂| 国产精品久久影视| 午夜精品久久久久久久久久| 国产黄色大片免费看| 国产mv日韩mv欧美| 99草草国产熟女视频在线| 亚洲精品成人无限看| 精品久久久久久一区二区里番| 国产成人毛片| 午夜精品福利电影| 欧美激情二区| 亚洲精品一区二区三区婷婷月 | 亚洲精品在线观看视频| 中文字幕+乱码+中文乱码www| 亚洲精品日产精品乱码不卡| 成人黄色免费网址| 丁香一区二区三区| 欧美成人福利在线观看| 国产偷自视频区视频一区二区| 在线观看亚洲视频啊啊啊啊| 久久这里只有精品一区二区| 国产在线98福利播放视频| 麻豆视频在线观看免费网站黄| 精品国产自在精品国产浪潮 | 久久精品精品电影网| 日韩av视屏| 亚洲成人黄色网| 国产日韩欧美视频在线观看| 欧美亚洲精品一区| 国产69精品久久久久久久久久| 国产精品视频你懂的| 国产精品1000部啪视频| 成人性生交大片免费| 香蕉视频xxxx| 韩国理伦片一区二区三区在线播放 | 狂野欧美性猛交| 成人动漫中文字幕| 小日子的在线观看免费第8集| 99国内精品| 日韩欧美视频免费在线观看| 三上亚洲一区二区| 日韩免费一区二区三区| 欧美黑人巨大videos精品| dy888夜精品国产专区| www欧美在线观看| 国产美女精品视频免费观看| 欧美日韩国产v| 欧美在线亚洲在线| 午夜不卡影院| 91超碰中文字幕久久精品| 黄色在线看片| 欧美激情精品久久久久久久变态| 免费a级人成a大片在线观看| 在线视频免费一区二区| 国产三级电影在线观看| 亚洲欧美精品在线| 九色网友自拍视频手机在线| 日韩av在线电影网| 五月婷婷综合久久| 精品亚洲一区二区三区在线观看| 欧洲av在线播放| 亚洲成人精品视频| 天天射天天色天天干| 亚洲精品suv精品一区二区| 欧美熟妇交换久久久久久分类| 欧美变态tickle挠乳网站| 亚洲第一色视频| 欧美精品一区二区三区四区 | 99re视频这里只有精品| 一级欧美一级日韩片| 91视频观看免费| 一级黄色性视频| 国产精品无码永久免费888| 粉嫩精品久久99综合一区| 国产精品欧美经典| 国产精品 欧美激情| 亚洲一区视频在线观看视频| 日本一区二区三区免费视频| 色综合一区二区| 在线观看免费视频a| 日韩一区二区三区视频在线| 欧美 中文字幕| 亚洲欧美国产va在线影院| 99re热久久这里只有精品34| 久久精品国产v日韩v亚洲| 欧美videosex性极品hd| 国内外成人免费激情在线视频网站| h片在线观看视频免费免费| 日av在线播放中文不卡| 久久久久黄色| 国产精品久久久久免费| 亚洲成人一品| www亚洲国产| 国产亚洲一区在线| 蜜桃免费在线视频| 成人一级片网址| 久久美女免费视频| 一区二区三区四区乱视频| 日本特级黄色片| 欧美男男青年gay1069videost| 成人免费视频国产免费麻豆| 亚洲视频视频在线| 99在线播放| 国产a级全部精品| 欧美另类中文字幕| 欧美日韩精品不卡| 国产精品v亚洲精品v日韩精品 | 欧美艳星kaydenkross| 91精品久久久久久久久久| 加勒比视频一区| 亚洲综合av一区| 国产一区二区精品| 一级片黄色免费| 国产亚洲精品aa午夜观看| 久久久久97国产| 欧美色视频在线观看| 色噜噜一区二区三区| 中文字幕在线观看日韩| 福利影院在线看| 草莓视频一区| 999精品一区| 欧美精品成人网| 99久久精品国产网站| 亚洲区一区二区三| 色狠狠av一区二区三区| 人妻无码一区二区三区久久99| 日韩一区二区福利| 欧美一级大黄| 久久99精品久久久久久青青日本| 91精品国产视频| 色综合天天色综合| 91女神在线视频| 精品一级少妇久久久久久久| 欧美一区二区在线看| 第一页在线观看| 庆余年2免费日韩剧观看大牛| 777久久精品| 久久综合亚洲精品| 久草在线在线精品观看| 欧美xxxx精品| 欧洲亚洲精品在线| 国产在线一二| 青青草一区二区| 色先锋久久影院av| 久艹视频在线免费观看| 成人精品鲁一区一区二区| 成年人av电影| 欧美一卡二卡在线| 黄网站在线播放| 91在线观看免费网站| 欧美oldwomenvideos| 久久99爱视频| 中文字幕国产精品一区二区| 无码视频在线观看| 国产香蕉一区二区三区在线视频 | 精品人妻无码一区| 91久久精品一区二区二区| 欧美美乳在线| 日韩美女视频免费看| 最新国产精品视频| 日本xxxxxxx免费视频| 久久免费看少妇高潮| 日本黄色中文字幕| 国产午夜精品美女视频明星a级| 婷婷激情一区| 亚洲精美视频| 久久91精品久久久久久秒播| 男人av资源站| 日韩精品一区二区三区中文不卡 | 色妞www精品视频| 国产高清视频在线| 国产免费一区二区三区香蕉精| 97色伦图片97综合影院| 日批视频在线看| 亚洲一卡二卡三卡四卡五卡| 特级丰满少妇一级aaaa爱毛片| 91av中文字幕| 成人精品天堂一区二区三区| 中文字幕在线观看日| 一二三区精品福利视频| 亚洲日本在线播放| 国产精品av电影| 婷婷亚洲五月| 怡红院一区二区| 色天天综合久久久久综合片| 在线免费观看黄| 国产精品免费在线| 亚洲欧美激情诱惑| 顶级黑人搡bbw搡bbbb搡| 欧美videossexotv100| 中文在线8资源库| 在线丝袜欧美日韩制服| 国产jizzjizz一区二区| 黄色av一级片| 久久6精品影院| 亚洲精品推荐| 亚洲免费在线播放视频| 午夜精品福利在线| 91高清在线视频| 国偷自产av一区二区三区小尤奈| 天堂精品中文字幕在线| 国产一区二区播放| 国产视频精品va久久久久久| 亚洲精品成人一区| 亚洲熟妇av一区二区三区| 中文字幕一区二区在线播放| 嫩草影院一区二区| 国产免费一区视频观看免费| 亚洲免费播放| 麻豆网址在线观看| 亚洲人在线视频| 高清日韩欧美| 亚洲一级片av| 在线免费观看日本欧美|