自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

幫你精通JS: 函數(shù)式array.forEach的8個案例

開發(fā) 前端
JavaScript是當今流行語言中對函數(shù)式編程支持最好的編程語言。我們繼續(xù)構建函數(shù)式編程的基礎,接下來,我們將學習更加通用的函數(shù)式迭代方法 array.forEach()。

[[387134]]

 JavaScript是當今流行語言中對函數(shù)式編程支持最好的編程語言。我們繼續(xù)構建函數(shù)式編程的基礎,在前文中分解介紹了幫助我們組織思維的四種方法,分別為:

- array.reduce方法 幫你精通JS:神奇的array.reduce方法的10個案例

- array.map方法 幫你精通JS:神奇的array.map的6個案例

- array.flat方法,以及array.flatMap 幫你精通JS: array.flat與flatMap用法指南

以上四種方法的共同點都是對array作轉換和變形,而且都不需要陷入到瑣碎loop實現(xiàn)細節(jié)的 dirty details之中。

接下來,我們將學習更加通用的函數(shù)式迭代方法 array.forEach()。

一句話概括區(qū)分 forEach 與 map 的區(qū)別,pure-function 就用 map,impure-function 則用 forEach。

array.forEach() 語法概述

forEach() 方法對數(shù)組的每個元素執(zhí)行一次給定的函數(shù)。

  1. const array1 = ['a''b''c']; 
  2.  
  3. array1.forEach(element => console.log(element)); 
  4.  
  5. // expected output"a" 
  6. // expected output"b" 
  7. // expected output"c" 

 參數(shù)

callback

為數(shù)組中每個元素執(zhí)行的函數(shù),該函數(shù)接收一至三個參數(shù):

- currentValue 數(shù)組中正在處理的當前元素。

- index 可選 數(shù)組中正在處理的當前元素的索引。

- array 可選 forEach() 方法正在操作的數(shù)組。

thisArg 可選 可選參數(shù)。當執(zhí)行回調函數(shù) callback 時,用作 this 的值。

返回值

undefined。

array.forEach() 描述

forEach() 方法按升序為數(shù)組中含有效值的每一項執(zhí)行一次 callback 函數(shù),那些已刪除或者未初始化的項將被跳過(例如在稀疏數(shù)組上)。

可依次向 callback 函數(shù)傳入三個參數(shù):

  1. 數(shù)組當前項的值
  2. 數(shù)組當前項的索引
  3. 數(shù)組對象本身

如果 thisArg 參數(shù)有值,則每次 callback 函數(shù)被調用時,this 都會指向 thisArg 參數(shù)。如果省略了 thisArg 參數(shù),或者其值為 null 或 undefined,this 則指向全局對象。按照函數(shù)觀察到 this 的常用規(guī)則,callback 函數(shù)最終可觀察到 this 值。

forEach() 遍歷的范圍在第一次調用 callback 前就會確定。調用 forEach 后添加到數(shù)組中的項不會被 callback 訪問到。如果已經(jīng)存在的值被改變,則傳遞給 callback 的值是 forEach() 遍歷到他們那一刻的值。已刪除的項不會被遍歷到。如果已訪問的元素在迭代時被刪除了(例如使用 shift()),之后的元素將被跳過——參見下面的示例。

forEach() 為每個數(shù)組元素執(zhí)行一次 callback 函數(shù);與 map() 或者 reduce() 不同的是,它總是返回 undefined 值,并且不可鏈式調用。其典型用例是在一個調用鏈的最后執(zhí)行副作用(side effects,函數(shù)式編程上,指函數(shù)進行 返回結果值 以外的操作)。

forEach() 被調用時,不會改變原數(shù)組,也就是調用它的數(shù)組(盡管 callback 函數(shù)在被調用時可能會改變原數(shù)組)。(此處說法可能不夠明確,具體可參考EMCA語言規(guī)范:'forEach does not directly mutate the object on which it is called but the object may be mutated by the calls to callback function.',即 forEach 不會直接改變調用它的對象,但是那個對象可能會被 callback 函數(shù)改變。)

注意: 除了拋出異常以外,沒有辦法中止或跳出 forEach() 循環(huán)。如果你需要中止或跳出循環(huán),forEach() 方法不是應當使用的工具。

若你需要提前終止循環(huán),你可以使用:

  • 一個簡單的 for 循環(huán)
  • for...of / for...in 循環(huán)
  • Array.prototype.every()
  • Array.prototype.some()
  • Array.prototype.find()
  • Array.prototype.findIndex()

這些數(shù)組方法則可以對數(shù)組元素判斷,以便確定是否需要繼續(xù)遍歷:

  • every()
  • some()
  • find()
  • findIndex()

只要條件允許,也可以使用 filter() 提前過濾出需要遍歷的部分,再用 forEach() 處理。

案例 01 不對未初始化的值進行任何操作(稀疏數(shù)組)

如你所見,3 和 7 之間空缺的數(shù)組單元未被 forEach() 調用 callback 函數(shù),或進行任何其他操作。

  1. const arraySparse = [1,3,,7]; 
  2. let numCallbackRuns = 0; 
  3.  
  4. arraySparse.forEach(function(element){ 
  5.   console.log(element); 
  6.   numCallbackRuns++; 
  7. }); 
  8.  
  9. console.log("numCallbackRuns: ", numCallbackRuns); 
  10.  
  11. // 1 
  12. // 3 
  13. // 7 
  14. // numCallbackRuns: 3 

 案例 02 將 for 循環(huán)轉換為 forEach

  1. const items = ['item1''item2''item3']; 
  2. const copy = []; 
  3.  
  4. // before 
  5. for (let i=0; i<items.length; i++) { 
  6.   copy.push(items[i]); 
  7.  
  8. // after 
  9. items.forEach(function(item){ 
  10.   copy.push(item); 
  11. }); 

 案例 03 打印出數(shù)組的內容

注意:為了在控制臺中顯示數(shù)組的內容,你可以使用 console.table() 來展示經(jīng)過格式化的數(shù)組。下面的例子則是另一種使用 forEach() 的格式化的方法。

下面的代碼會為每一個數(shù)組元素輸出一行記錄:

  1. function logArrayElements(element, index, array) { 
  2.   console.log('a[' + index + '] = ' + element); 
  3.  
  4. // 注意索引 2 被跳過了,因為在數(shù)組的這個位置沒有項 
  5. [2, 5, , 9].forEach(logArrayElements); 
  6. // logs: 
  7. // a[0] = 2 
  8. // a[1] = 5 
  9. // a[3] = 9 

 案例 04 使用 thisArg

舉個勉強的例子,按照每個數(shù)組中的元素值,更新一個對象的屬性:

  1. function Counter() { 
  2.   this.sum = 0; 
  3.   this.count = 0; 
  4. Counter.prototype.add = function(array) { 
  5.   array.forEach(function(entry) { 
  6.     this.sum += entry; 
  7.     ++this.count
  8.   }, this); 
  9.   // ^---- Note 
  10. }; 
  11.  
  12. const obj = new Counter(); 
  13. obj.add([2, 5, 9]); 
  14. obj.count
  15. // 3 === (1 + 1 + 1) 
  16. obj.sum
  17. // 16 === (2 + 5 + 9) 

 因為 thisArg 參數(shù)(this)傳給了 forEach(),每次調用時,它都被傳給 callback 函數(shù),作為它的 this 值。

注意:如果使用箭頭函數(shù)表達式來傳入函數(shù)參數(shù), thisArg 參數(shù)會被忽略,因為箭頭函數(shù)在詞法上綁定了 this 值。

案例 05 對象復制器函數(shù)

下面的代碼會創(chuàng)建一個給定對象的副本。 創(chuàng)建對象的副本有不同的方法,以下是只是一種方法,并解釋了 Array.prototype.forEach() 是如何使用 ECMAScript 5 Object.* 元屬性(meta property)函數(shù)工作的。

  1. function copy(obj) { 
  2.   const copy = Object.create(Object.getPrototypeOf(obj)); 
  3.   const propNames = Object.getOwnPropertyNames(obj); 
  4.  
  5.   propNames.forEach(function(name) { 
  6.     const desc = Object.getOwnPropertyDescriptor(obj, name); 
  7.     Object.defineProperty(copy, namedesc); 
  8.   }); 
  9.  
  10.   return copy; 
  11.  
  12. const obj1 = { a: 1, b: 2 }; 
  13. const obj2 = copy(obj1); // 現(xiàn)在 obj2 看起來和 obj1 一模一樣了 

 案例 06 如果數(shù)組在迭代時被修改了,則其他元素會被跳過。

下面的例子會輸出 "one", "two", "four"。當?shù)竭_包含值 "two" 的項時,整個數(shù)組的第一個項被移除了,這導致所有剩下的項上移一個位置。因為元素 "four" 正位于在數(shù)組更前的位置,所以 "three" 會被跳過。 forEach() 不會在迭代之前創(chuàng)建數(shù)組的副本。

  1. var words = ['one''two''three''four']; 
  2. words.forEach(function(word) { 
  3.   console.log(word); 
  4.   if (word === 'two') { 
  5.     words.shift(); 
  6.   } 
  7. }); 
  8. // one 
  9. // two 
  10. // four 

 案例 07 扁平化數(shù)組

下面的示例僅用于學習目的。如果你想使用內置方法來扁平化數(shù)組,你可以考慮使用 Array.prototype.flat()(預計將成為 ES2019 的一部分,并且已在主要瀏覽器中實現(xiàn))或參考其 polyfill。

  1. /** 
  2.  * Flattens passed array in one dimensional array 
  3.  * 
  4.  * @params {array} arr 
  5.  * @returns {array} 
  6.  */ 
  7. function flatten(arr) { 
  8.   const result = []; 
  9.  
  10.   arr.forEach((i) => { 
  11.     if (Array.isArray(i)) 
  12.       result.push(...flatten(i)); 
  13.     else 
  14.       result.push(i); 
  15.   }) 
  16.  
  17.   return result; 
  18.  
  19. // Usage 
  20. const problem = [1, 2, 3, [4, 5, [6, 7], 8, 9]]; 
  21.  
  22. flatten(problem); // [1, 2, 3, 4, 5, 6, 7, 8, 9] 

 案例08 針對 promise 或 async 函數(shù)的使用備注

如果使用 promise 或 async 函數(shù)作為 forEach() 等類似方法的 callback 參數(shù),最好對造成的執(zhí)行順序影響多加考慮,否則容易出現(xiàn)錯誤。

  1. let ratings = [5, 4, 5]; 
  2.  
  3. let sum = 0; 
  4.  
  5. let sumFunction = async function (a, b) { 
  6.     return a + b; 
  7.  
  8. ratings.forEach(async function(rating) { 
  9.     sum = await sumFunction(sum, rating); 
  10. }) 
  11.  
  12. console.log(sum); 
  13. // Expected output: 14 
  14. // Actual output: 0 

 【編輯推薦】

 

責任編輯:姜華 來源: 今日頭條
相關推薦

2021-03-14 08:12:02

函數(shù)JavaScript語言

2021-03-17 06:03:41

函數(shù)式編程JavaScriptarray.filte

2025-03-17 08:30:00

JavaScript循環(huán)代碼

2021-03-05 07:45:59

JSreducemap

2021-04-08 09:14:24

js前端函數(shù)

2021-07-01 09:43:44

Python函數(shù)參數(shù)

2019-10-15 09:05:07

域插槽組件前端

2020-12-22 14:11:45

JS forEach()map()

2018-06-19 14:52:52

2012-05-09 09:49:57

移動支付

2024-01-16 12:19:08

MySQL重要機制高并發(fā)

2025-03-27 10:03:17

PythonPandas代碼

2022-03-14 09:25:58

B 端UI信息密度

2011-03-30 13:03:14

數(shù)據(jù)庫營銷

2021-04-07 08:03:51

js舉起Hoisting初始化

2025-04-24 10:20:00

2016-11-28 08:56:15

透析大數(shù)據(jù)核心

2011-03-31 11:15:52

網(wǎng)頁設計Web

2020-03-12 14:40:59

Python表格命令行

2017-11-10 09:30:43

Linux系統(tǒng)啟動故障修復
點贊
收藏

51CTO技術棧公眾號