精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

制服丝袜av在线| 国内爆初菊对白视频| 国产剧情在线| 国产精品18久久久久久vr| 欧美成人精品h版在线观看| 国产大学生av| 88xx成人免费观看视频库 | 亚洲AV无码久久精品国产一区| 伊人电影在线观看| 久久精品视频在线免费观看| 成人精品一区二区三区电影免费 | 国产欧美日韩最新| 精品深夜av无码一区二区老年| 国产成人ay| 日韩你懂的电影在线观看| 丰满人妻中伦妇伦精品app| 日韩精品成人av| 91首页免费视频| 91久久久亚洲精品| 亚洲精品一区二三区| 国内综合精品午夜久久资源| 亚洲最新av在线网站| 涩视频在线观看| 伊人久久综合网另类网站| 精品久久久久久中文字幕一区奶水 | 国内不卡的一区二区三区中文字幕| 亚洲成人av电影在线| 一区二区三区不卡在线| 天堂av在线播放| 国产精品一区二区免费不卡| 国产99久久精品一区二区永久免费| 久久久久久久久毛片| 成人无号精品一区二区三区| 精品无人国产偷自产在线| 麻豆传媒在线看| 欧美网站免费| 欧美影院精品一区| 国产精品免费入口| 波多野结衣久久| 亚洲摸摸操操av| 中国成人在线视频| 一广人看www在线观看免费视频| 久久久噜噜噜久噜久久综合| 国产日韩欧美亚洲一区| 精品国产伦一区二区三区| 久久精品国产99| 国产精品中文在线| 中文字幕av第一页| 久久中文在线| 日本亚洲欧洲色α| 国内自拍视频在线播放| 亚洲在线一区| 欧美一级片一区| 丰满少妇乱子伦精品看片| 欧美日韩国产亚洲一区| 欧美久久久精品| 九九九久久久久| 一区二区自拍| 91av视频在线| 无码人妻av免费一区二区三区| 亚洲自啪免费| 国产97在线视频| 中国一区二区视频| 久久99久久精品欧美| 91理论片午午论夜理片久久| 99精品视频在线播放免费| 国产毛片精品视频| 91观看网站| 少妇av在线播放| 久久久精品欧美丰满| 久久一区二区三区欧美亚洲| 国产精品一二三区视频| 国产精品国产三级国产aⅴ入口 | 美女免费久久| 亚洲精品免费在线观看| 在线观看视频黄色| 91九色在线播放| 欧美亚洲综合一区| 午夜大片在线观看| 玖玖玖免费嫩草在线影院一区| 精品亚洲精品福利线在观看| 日本高清黄色片| 91精品国产视频| 91精品国产777在线观看| 超碰在线观看91| 精彩视频一区二区| 国产亚洲欧美一区二区三区| 国产一级在线| 亚洲综合视频在线| 蜜臀久久99精品久久久酒店新书| 国产美女久久| 亚洲白虎美女被爆操| 亚洲黄色小说视频| 自拍日韩欧美| 国产97在线播放| www.五月婷婷| 国产亚洲精品bt天堂精选| 亚洲成年人专区| 久久青青视频| 日韩免费一区二区三区在线播放| 18禁裸乳无遮挡啪啪无码免费| 日本高清免费电影一区| 久久免费视频这里只有精品| 岳乳丰满一区二区三区| 99热精品国产| 伊人网在线免费| 日本中文字幕一区二区| 亚洲国产女人aaa毛片在线| 国产视频123区| 国产欧美一区二区三区国产幕精品| 国产欧美日韩专区发布| 久久伊伊香蕉| 亚洲高清免费观看高清完整版在线观看| 97xxxxx| 亚洲精品黑牛一区二区三区| 国产小视频国产精品| 日韩欧美性视频| 韩国三级中文字幕hd久久精品| 美脚丝袜一区二区三区在线观看| h片在线播放| 欧美日本在线观看| 美女洗澡无遮挡| 精品白丝av| 99se婷婷在线视频观看| 素人av在线| 在线视频一区二区免费| 97人妻天天摸天天爽天天| 中文字幕一区二区三三| 91九色视频导航| 91大神xh98hx在线播放| 在线观看免费亚洲| 久久久久亚洲av无码专区桃色| 精品96久久久久久中文字幕无| 91中文在线视频| 91美女视频在线| 91福利视频在线| 少妇大叫太粗太大爽一区二区| 极品av少妇一区二区| 成人免费在线一区二区三区| www在线免费观看视频| 欧美久久久久久久久中文字幕| 阿v天堂2014| 日本午夜一本久久久综合| 欧美日韩一区二区视频在线观看| 午夜av不卡| 精品亚洲精品福利线在观看| 一本一道无码中文字幕精品热| 99九九99九九九视频精品| 日韩a∨精品日韩在线观看| 亚洲精品在线国产| 久久久亚洲福利精品午夜| 亚洲黄色一级大片| 亚洲成a人在线观看| 色婷婷精品久久二区二区密| 亚洲欧洲一区| 国产一区二区精品免费| 欧美日韩国产观看视频| 亚洲精品一区中文字幕乱码| 免费看毛片网站| 国产欧美精品在线观看| 亚洲国产日韩欧美在线观看| 国产精品久久久久久| 亚洲一区二区三区777| 欧美日韩经典丝袜| 国产视频自拍一区| 亚洲图片欧美日韩| 一区在线中文字幕| 国产伦理在线观看| 在线亚洲一区| 神马影院一区二区| 国产精品高清一区二区| 久久免费精品日本久久中文字幕| 偷拍自拍在线| 欧美怡红院视频| 久久精品黄色片| 成人国产亚洲欧美成人综合网| 日韩精品xxxx| 99成人在线视频| 国产成人精品福利一区二区三区| 中文字幕在线看片| 久久精品国产v日韩v亚洲| 丰满少妇在线观看bd| 色婷婷综合五月| 麻豆视频在线免费看| av高清久久久| 亚洲一级免费观看| 国产精品99一区二区| 欧美在线视频一区二区三区| 最新亚洲国产| 91av在线免费观看| 黄色小网站在线观看| 精品视频中文字幕| 国产人妻精品一区二区三区| 精品久久久久久亚洲精品| 成年人网站在线观看视频| 99re在线精品| 青娱乐国产精品视频| 久久精品官网| 免费网站在线观看视频| 青青草原综合久久大伊人精品| 999国产在线| 欧美大胆性生话| 欧美激情综合色综合啪啪五月| 国产中文字幕在线| 亚洲国产古装精品网站| 国产又黄又猛又爽| 色哟哟一区二区在线观看| 国产一二三四在线| 国产精品美女视频| 亚洲av无码一区二区三区观看| 极品少妇一区二区| av免费网站观看| 精品动漫3d一区二区三区免费版| 正义之心1992免费观看全集完整版| 日本一区福利在线| 成人三级在线| 99综合久久| 国产精品久久久久久av下载红粉| 成人影院在线视频| 欧美精品福利在线| av在线下载| 日韩中文理论片| 看电影就来5566av视频在线播放| 亚洲成年人在线播放| 精品国产va久久久久久久| 欧美日韩日日摸| 最近国语视频在线观看免费播放| 午夜精品爽啪视频| 久草网在线观看| 亚洲美女免费在线| fc2ppv在线播放| 欧美国产日本视频| 国产免费看av| www成人在线观看| 一区二区免费在线观看视频| 成人亚洲一区二区一| 熟女人妻一区二区三区免费看| 狠狠色狠狠色综合系列| 国产精品v日韩精品v在线观看| 日韩av成人高清| 热久久精品免费视频| 日日夜夜免费精品视频| 日批视频在线免费看| 国产欧美成人| 能在线观看的av| 老鸭窝亚洲一区二区三区| 精品一卡二卡三卡| 日韩黄色在线观看| 91蝌蚪视频在线观看| 日韩电影在线一区| 成人日韩在线视频| 国产美女一区二区三区| 91大神免费观看| 粉嫩av亚洲一区二区图片| 中国特级黄色大片| 久久伊人中文字幕| 欧美激情 一区| 国产精品久久久久久亚洲伦| 亚洲 欧美 国产 另类| 亚洲精品视频一区| 久草视频精品在线| 色综合久久久久久久久久久| 青娱乐在线免费视频| 91麻豆精品国产91久久久更新时间| 国产99久久九九精品无码免费| 欧美tk—视频vk| 五月婷婷激情在线| 国产一区二区三区精品久久久| 美女隐私在线观看| 亚洲3p在线观看| 电影亚洲精品噜噜在线观看| 91精品久久久久久久| 欧美成人精品一级| 精品国产一区二区三区麻豆免费观看完整版 | 奇米亚洲午夜久久精品| √天堂资源在线| 99热这里都是精品| 国产三级短视频| 一区二区三区欧美久久| 国产无人区码熟妇毛片多| 欧美性色aⅴ视频一区日韩精品| 国产又黄又大又爽| 日韩电视剧在线观看免费网站| av网站无病毒在线| 欧美激情a∨在线视频播放| 中文字幕乱码在线播放| 国产日韩欧美成人| 免费看久久久| 亚洲精品电影在线一区| 在线不卡欧美| 三上悠亚在线一区| 久久综合色之久久综合| 免费成人美女女在线观看| 午夜精品久久久久久久99樱桃| 中文字幕乱码人妻无码久久| 精品久久人人做人人爱| 日韩精品国产一区二区| 国产精品探花在线| 99精品免费| 欧美三级免费观看| 国产精品香蕉av| 五月天丁香花婷婷| 亚洲精品一区二区三区区别| 国产亚洲精品自拍| 成人小视频在线观看免费| 久久精品一区二区三区中文字幕| 成人在线国产精品| 日韩伦理三区| av一区二区在线看| 色无极亚洲影院| 日本十八禁视频无遮挡| 国产一区视频网站| 国产1区2区在线观看| 亚洲国产另类精品专区| 日本大片免费看| 欧美日韩三级电影在线| 91制片厂毛片| 久久日一线二线三线suv| 免费一级片在线观看| 欧美精品在线视频| www视频在线观看免费| 8x拔播拔播x8国产精品| 51vv免费精品视频一区二区| 免费成人进口网站| 麻豆国产欧美日韩综合精品二区| 久久无码人妻精品一区二区三区| 亚洲综合一区二区| 99精品人妻无码专区在线视频区| 色偷偷888欧美精品久久久| 丝袜美腿一区| 欧美精品国产精品久久久 | 日本欧美韩国| 欧美日韩精品免费观看| 国产亚洲激情| 免费看黄色aaaaaa 片| 亚洲成人一二三| 欧美少妇bbw| 久久久视频免费观看| 日韩在线成人| 国产911在线观看| 国产乱一区二区| 国产免费无码一区二区视频| 制服丝袜中文字幕亚洲| www免费在线观看| 亚洲精品日韩激情在线电影| 99久久亚洲精品蜜臀| www.五月天色| 亚洲精品乱码久久久久| 亚洲av无码乱码国产精品久久| 久久99热这里只有精品国产| 精品国产一区二| r级无码视频在线观看| 99免费精品在线| 亚洲 欧美 中文字幕| 中文字幕在线视频日韩| 成人在线日韩| 欧美一级爱爱视频| 成人久久视频在线观看| 国产一级精品视频| 亚洲性xxxx| 国产91在线播放精品| 综合操久久久| 国产suv精品一区二区三区| www.youjizz.com亚洲| 精品视频久久久久久| 日韩av电影资源网| 自拍偷拍视频在线| 国产91精品精华液一区二区三区 | 在线一区二区三区四区| aaa日本高清在线播放免费观看| 国产日韩在线免费| 欧美不卡高清| 五月婷婷综合在线观看| 欧美视频一区二| 成人在线网址| 极品校花啪啪激情久久| 人人爽香蕉精品| 青青草原免费观看| 日韩av网址在线观看| 日本中文字幕一区二区| 乱熟女高潮一区二区在线| 久久亚洲私人国产精品va媚药| 亚洲天堂国产精品| 午夜精品三级视频福利| 成人一区不卡| 中文字幕视频观看| 日本韩国一区二区三区视频| 黄网站在线播放| 欧美12av| 国产精品1区二区.| 麻豆成人免费视频| 久久亚洲影音av资源网 | 久久免费看毛片| k8久久久一区二区三区| 97人妻精品视频一区| 欧美精品www| 欧美aaaa视频| 亚洲一级中文字幕| 欧美不卡视频一区| 成人免费毛片嘿嘿连载视频…|