來自數組原型 Array.prototype 的遍歷函數


 

1. Array.prototype.forEach()

forEach() 是一個專為遍歷數組而生的方法,它沒有返回值,也不會改變原數組,只是簡單粗暴的將數組遍歷一次

 參數:

callback() 必填 在數組每一項上執行的函數
thisArg  可選 執行回掉時用作 this 的對象

 

  

 

如果傳入了參數 thisArg在 callback() 內部的 this 都會指向 thisArg(箭頭函數除外)

 

callback 參數:

item  當前遍歷到的數組元素
index 當前元素的索引
array  被遍歷的數組本身

 

 

  

 

const arr = [1, 2, 3]; arr.forEach((item, index, array) => { console.log(index, item, array); });

但 forEach() 無法中止遍歷(除非出現錯誤),所以如果希望在遍歷過程中跳出循環,不建議使用 forEach()

 

 

2. Array.prototype.map()

map() 在遍歷數組的時候,會接收 callback() 的返回值作為新數組的元素,最后返回這個新數組

 參數:

callback() 必填 在數組每一項上執行的函數
thisArg  可選 執行回掉時用作 this 的對象

 

 

 

callback 參數:

item  當前遍歷到的數組元素
index 當前元素的索引
array  被遍歷的數組本身

 

 

 

  

const arr = [1, 2, 3]; arr.map((item, index, array) => { return item + index; });
// [1, 3, 5]

同樣的,map() 不會修改原數組,也不能提前中止循環

由於 map() 會基於 callback() 的返回值創建新數組,所以有一些特別的用法,比如將字符串數組轉為 Number 類型:

let arr = ['1', '2', '3']; arr = arr.map(Number); // [1, 2, 3]

 

 

3. Array.prototype.filter()

filter() 可以基於測試函數 callback() 的返回值,篩選出原數組中符合條件的元素,組成新數組並返回

參數: 

callback() 必填 在數組每一項上執行的函數
thisArg  可選 執行回掉時用作 this 的對象

 

  

 

callback 參數:

item  當前遍歷到的數組元素
index 當前元素的索引
array  被遍歷的數組本身

 

 

 

 

和 map() 不同的是,map() 中 callback() 的返回值會直接作為新數組的元素

而 filter() 會基於 callback() 的結果,判斷是否將原數組的對應元素過濾掉

如果 callback() 的返回值為 true 或者等價於 true 的值(truthy),則保留該元素,否則排除該元素,最后返回新數組

const arr = [1, 3, 20, 8, 12, 18]; arr.filter((item, index, array) => { return item > 10; }); // [20, 12, 18]

filter() 不會修改原數組,也不能提前結束遍歷

 

 

4. Array.prototype.every()

every() 是一個檢測數組的方法,可以傳入一個檢測函數作為 callback()

 參數: 

callback() 必填 在數組每一項上執行的函數
thisArg  可選 執行回掉時用作 this 的對象

 

 

 

callback 參數:

item  當前遍歷到的數組元素
index 當前元素的索引
array  被遍歷的數組本身

 

 

 

 

如果這個檢測函數每次都返回 true(truthy),則 every() 會返回 true

every() 會按照數組的順序,為每個數組元素執行一次 callback() 方法,如果有一個返回值為 false,則停止遍歷,並返回 false

const arr = [1, '2', 'name', 0]; arr.every((item, index, array) => { console.log(item); return typeof item === 'number'; }); // 1 -> '2' -> false

 

 

5. Array.prototype.some()

some() 和 every() 類似,他們的區別僅僅是“且”和“或”的區別

every() 需要所有元素都滿足條件才會返回 true,而 some() 只要有一個元素滿足條件,就立刻返回 true

 參數: 

callback() 必填 在數組每一項上執行的函數
thisArg  可選 執行回掉時用作 this 的對象

 

 

 

callback 參數: 

item  當前遍歷到的數組元素
index 當前元素的索引
array  被遍歷的數組本身

 

 

 

  

const arr = [1, '2', 'name', 0]; arr.some((item, index, array) => { console.log(item); return typeof item === 'number'; }); // 1 -> true

 


6. Array.prototype.find()

 find() 可以接收一個 callback() 作為檢測函數,返回數組中第一個滿足條件的元素並中止遍歷,否則返回 undefined

 參數: 

callback() 必填 在數組每一項上執行的函數
thisArg  可選 執行回掉時用作 this 的對象

 

 

 

callback 參數: 

item  當前遍歷到的數組元素
index 當前元素的索引
array  被遍歷的數組本身

 

 

 

 

const arr = [ { id: 1, name: 'lee' }, { id: 2, name: 'rock' }, { id: 3, name: 'poly' } ]; arr.find((item, index, array) => { return item.id > 1; }); // {id: 2, name: "rock"}

 

  

7. Array.prototype.findIndex() 

findIndex() 是 find() 的孿生兄弟,find() 會返回元素的值,而 findIndex() 會返回元素的索引

參數: 

callback() 必填 在數組每一項上執行的函數
thisArg  可選 執行回掉時用作 this 的對象

 

 

 

callback 參數: 

item  當前遍歷到的數組元素
index 當前元素的索引
array  被遍歷的數組本身

 

 

 

 

const arr = [ { id: 1, name: 'lee' }, { id: 2, name: 'rock' }, { id: 3, name: 'poly' } ]; arr.find((item, index, array) => { return item.id > 1; }); // 1

如果沒有滿足條件的元素,則返回 -1

 

  

8. Array.prototype.indexOf() 

indexOf() 用於查找某個元素在數組中的第一個索引,若無則返回 -1

參數: 

item 必填 目標元素
startIndex  可選 開始查找的位置,默認為 0,如果是負值,則從末尾開始查找

 

 

 

這里的 startIndex 即使傳入負值,數組遍歷的順序也不會改變,依然是從前往后遍歷

const arr = [1, 2, 3]; arr.indexOf(2); // 1

 

如果目標值是一個 Object,這里就會有一些出乎意料的結果

const arr = [ { id: 1, name: 'lee' }, { id: 2, name: 'rock' }, { id: 3, name: 'poly' } ]; arr.indexOf({ id: 1, name: 'lee' }); // -1

這里的目標元素  {id: 1, name: 'lee'} 明明存在於 arr 中,但 indexOf() 返回的索引卻是 -1

這是因為 JS 的 Object 都存放在堆內存里面,上面的代碼其實在堆內存中創建了兩個對象 {id: 1, name: 'lee'}

雖然這兩個對象看起來一模一樣,但本身依舊是兩個對象,所以 indexOf() 的返回值為 -1

const obj1 = {id: 1, name: 'lee'}, obj2 = {id: 2, name: 'rock'}, obj3 = {id: 3, name: 'poly'}; const arr = [obj1, obj2, obj3]; arr.indexOf(obj1); // 0

如果像上面這樣,將對象保存在一個變量中,這個變量實際保存的是這個對象的指針

arr 基於指針添加元素,indexOf() 查找的也是指針,這樣就能返回正確的索引

但實際業務中很少會有基於對象指針創建數組的情況,所以一般不用 indexOf 來檢測對象數組

 

 

9. Array.prototype.includes()

includes() 和 indexOf() 類似,區別在於 indexOf() 會返回索引,而 includes() 只返回 ture 或 false

參數: 

item 必填 目標元素
startIndex  可選 開始查找的位置,默認為 0,如果是負值,則從末尾開始查找

 

 

 

const arr = ['a', 'b', 'c']; arr.includes('a'); // true
arr.includes('a', -2); // false

由於上面提到過的原因,對象數組不能使用 includes 方法來檢測

 

 

10.  Array.prototype.reduce()

reduce() 會對數組的每一個元素執行 callback() 函數

在遍歷過程中,每次 callback() 的返回值,都會在下次調用 callback() 的時候,作為參數 accumulator 傳進去,最終匯總為單個返回值

參數: 

callback() 必填 在數組每一項上執行的函數
initialValue  可選 作為第一次調用 callback() 時的第一個參數。如果沒有提供初始值,則使用數組中的第一個元素。

 

 

 

callback 參數: 

accumulator 累計值
item  當前遍歷到的數組元素
index 當前元素的索引
array  被遍歷的數組本身

 

 

 

 

 

const arr = [1, 2, 3, 4, 5, 6]; arr.reduce((acc, item, index, array) => { return acc + item; }); // 1 + 2 + 3 + 4 + 5 + 6 = 21

基於累加的特性,可以實現數組去重

const arr = [1, 2, 1, 2, 4, 5, 3, 5]; arr.reduce((acc, item) => { if (!acc.includes(item)) { return acc.concat(item) } else { return acc } }, []); //  [1, 2, 4, 5, 3]

以及數組的扁平化 flat

const arr = [1,2,3,[1,2,3,4, [2,3,4]]]; function flattenDeep(arr) { return arr.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val), [] ); } flattenDeep(arr); // [1, 2, 3, 1, 2, 3, 4, 2, 3, 4] // 等價於 -> arr.flat(Infinity)

需要注意的是,如果沒有提供初始值 initialValue,reduce 會從第二個元素開始執行 callback(),跳過第一個元素

如果提供初始值,則從第一個元素開始。如果數組為空且沒有提供初始值,則報錯

如果數組僅有一個元素,且沒有初始值, 或者有初始值但是數組為空,那么此唯一值將被返回,並且不會執行 callback

 

 

11. reduceRight()

reduce() 是從左到右升序遍歷,而 reduceRIght() 的順序會反過來,從右到左降序遍歷 

參數: 

callback() 必填 在數組每一項上執行的函數
initialValue  可選 作為第一次調用 callback() 時的第一個參數。如果沒有提供初始值,則使用數組中的第一個元素。

 

 

 

callback 參數: 

accumulator 累計值
item  當前遍歷到的數組元素
index 當前元素的索引
array  被遍歷的數組本身

 

 

 

 

 

const arr = [0, 1, 2, 3, 4]; arr.reduceRight((acc, item) => { console.log('item', item); return acc + item; }); // 3 -> 2 -> 1 -> 0 -> 10

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM