JavaScript數組迭代(遍歷)方法


ES5和ES6中新增的的數組迭代方法如下:

  • forEach

  • map

  • filter

  • some

  • every

  • reduce / reduceRight

  • find / findIndex

其中,find / findIndex是ES6新增的,其余都是ES5新增的。所以這些方法對低版本IE都不兼容。
接下來我們看看這些方法如何使用並在低版本IE進行兼容。

forEach

forEach方法是這些方法里面最基本的一個方法,它的作用是對數組的每個元素執行一次提供的函數
例如:

var arr = [1, 2, 3]; arr.forEach(function (element, index, array) { console.log(element, index, array) }) //output 1 0 [1, 2, 3] 2 1 [1, 2, 3] 3 2 [1, 2, 3]

forEach方法中的callback函數會被依次傳入三個參數:

  • 數組當前項的值

  • 數組當前項的索引

  • 數組對象本身

forEach方法還可以傳入第二個參數,這個參數是可選的。如果給forEach傳遞了第二個參數,callback函數里的this將指向這個參數。如果沒有傳入第二個參數,則this指向全局對象(在瀏覽器是為window),嚴格模式下是undefined

var arr = [1, 2, 3]; var obj = {name: 'zhang'}; arr.forEach(function (element, index, array) { console.log(element, index, array, this) }, obj) // output 1 0 [1, 2, 3] {name: "zhang"} 2 1 [1, 2, 3] {name: "zhang"} 3 2 [1, 2, 3] {name: "zhang"}

下面我們用forEach寫一個稍顯完整的例子了,數組求和:

var sum = 0; [1, 2, 3].forEach(function (element, index, array) { console.log(array[index] == element); // true sum += item; }); console.log(sum); // 6

map

map方法的作用就是將原數組按照一定的規則映射成一個新的數組。再將其返回,是返回一個新的數組,而不是將原數組直接改變。使用方法和參數都跟forEach相似。
下面是一個數值求平方的例子:

var data = [1, 2, 3]; var arrayOfSquares = data.map(function (element) { return element * element; }); console.log(arrayOfSquares); //[1, 4, 9]

callback需要有return值,如果沒有,就像下面這樣:

var data = [1, 2, 3]; var arrayOfSquares = data.map(function (element) { element * element; }); console.log(arrayOfSquares); // [undefined, undefined, undefined]

 

filter

filter為“過濾”、“篩選”的意思。指數組filter后,返回過濾后的新數組。用法和參數跟map差不多。
與map方法不同的是,filter方法的callback函數需要返回弱等於truefalse的值。如果為true,則通過,否則,不通過。
例如:

var arr = [0, 1, 2, 3]; var newArr = arr.filter(function (element, index, array) { return e; }) var newArr2 = arr.filter(function (element, index, array) { return e>=2; }) console.log(newArr); // [1, 2, 3] console.log(newArr2); // [2, 3]

 

some

some方法是只要數組中的某個值,符合你給定的判斷條件就返回true;否則,返回false。用法和參數跟前面的方法一樣。
例如:

function isBigEnough(element, index, array) { return element >= 4; } var passed = [1, 2, 3].some(isBigEnough); var passed2 = [1, 2, 3, 4].some(isBigEnough); console.log(passed); // false console.log(passed2); // true

 

every

every方法與some方法相對,every方法是數組中的所有值都符合你給定的判斷條件的時候才會返回true,否則就返回false
例如:

function isBigEnough(element, index, array) { return element >= 3; } var passed = [2, 3, 4].every(isBigEnough); var passed2 = [3, 4, 5].every(isBigEnough); console.log(passed); // false console.log(passed2); // true

 

reduce / reduceRight

reduce / reduceRight 方法比上面的幾種方法要復雜一些;它的語法如下:

array.reduce(callback,[initialValue])

其中callback可以依次接受四個參數:

  • accumulator上一次調用回調返回的值,或者是提供的初始值(initialValue

  • currentValue數組中正在處理的元素

  • currentIndex數組中正在處理的元素索引,如果提供了initialValue ,從0開始;否則從1開始。

  • array數組對象本身

reduce / reduceRight 方法中,第二個參數(initialValue)是可選的;其值用於第一次調用callback的第一個參數。
我們先來看一個例子:

var sum = [1, 2, 3].reduce(function(a, b) { return a + b; }); console.log(sum); // 6

下面我們來看看reduce是如何運行的
例如執行下面這段代碼:

var sum = [0,1,2,3,4].reduce(function(accumulator, currentValue, currentIndex, array){ console.log(accumulator, currentValue, currentIndex, array) return accumulator + currentValue; }); console.log(sum); // output 0 1 1 [0, 1, 2, 3, 4] 1 2 2 [0, 1, 2, 3, 4] 3 3 3 [0, 1, 2, 3, 4] 6 4 4 [0, 1, 2, 3, 4] 10

從上面的輸出結果可以看出callback被調用四次,每次調用的參數和返回值如下表:

callback accumulator currentValue currentIndex array return
第一次調用 0 1 1 [0, 1, 2, 3, 4] 1
第二次調用 1 2 2 [0, 1, 2, 3, 4] 3
第三次調用 3 3 3 [0, 1, 2, 3, 4] 6
第四次調用 6 4 4 [0, 1, 2, 3, 4] 10

上面是沒有傳入第二個參數(initialValue)的情況,那傳入第二個參數又是怎么樣的呢?

var sum = [0,1,2,3,4].reduce(function(accumulator, currentValue, currentIndex, array){ console.log(accumulator, currentValue, currentIndex, array) return accumulator + currentValue; }, 10); console.log(sum); // output 10 0 0 [0, 1, 2, 3, 4] 10 1 1 [0, 1, 2, 3, 4] 11 2 2 [0, 1, 2, 3, 4] 13 3 3 [0, 1, 2, 3, 4] 16 4 4 [0, 1, 2, 3, 4] 20

傳入第二個參數后callback調用了五次,每次調用的參數和返回值如下表:

callback accumulator currentValue currentIndex array return
第一次調用 10 0 0 [0, 1, 2, 3, 4] 10
第二次調用 10 1 1 [0, 1, 2, 3, 4] 11
第三次調用 11 2 2 [0, 1, 2, 3, 4] 13
第四次調用 13 3 3 [0, 1, 2, 3, 4] 16
第五次調用 16 4 4 [0, 1, 2, 3, 4] 20

從上面的情況可以看出:不提供initialValue ,reduce方法會從索引1的地方開始執行callback方法,跳過第一個索引。提供 initialValue,從索引0開始。
同時,是否提供initialValue對於回調函數第一次執行時,accumulatorcurrentValue的取值有兩種情況:調用reduce時提供initialValueaccumulator取值為initialValuecurrentValue取數組中的第一個值;沒有提供initialValue ,accumulator取數組中的第一個值,currentValue取數組中的第二個值。

reduceRight與reduce類似,不同之處在於它是從最后一個值開始計算的。

那么我們該如何拓展一個reduce / reduceRight方法:

Array.prototype.reduce = Array.prototype.reduce || function (callback, initialValue ) { var previous = initialValue, k = 0, length = this.length; if (typeof initialValue === "undefined") { previous = this[0]; k = 1; } if (typeof callback === "function") { for (k; k < length; k++) { this.hasOwnProperty(k) && (previous = callback(previous, this[k], k, this)); } } return previous; }; Array.prototype.reduceRight = Array.prototype.reduceRight || function (callback, initialValue ) { var length = this.length, k = length - 1, previous = initialValue; if (typeof initialValue === "undefined") { previous = this[length - 1]; k--; } if (typeof callback === "function") { for (k; k > -1; k-=1) { this.hasOwnProperty(k) && (previous = callback(previous, this[k], k, this)); } } return previous; };

find / findIndex

find方法用於找出第一個符合條件的數組成員。它的參數跟forEach方法是一樣的;所有數組成員依次執行回調函數,直到找出第一個返回值為true的成員,然后返回該成員。如果沒有符合條件的成員,則返回undefined。
例如:

var value = [1, 5, 10, 15].find(function(element, index, array) { return element > 9; }); var value2 = [1, 5, 10, 15].find(function(element, index, array) { return element > 20; }); console.log(value); // 10 console.log(value2); // undefined

findIndex方法和find相似;不過它返回數組中符合條件的元素的索引。如果所有成員都不符合條件,則返回-1。

var value = [1, 5, 10, 15].findIndex(function(element, index, array) { return element > 9; }); var value2 = [1, 5, 10, 15].findIndex(function(element, index, array) { return element > 20; }); console.log(value); // 2 console.log(value2); // -1

 


免責聲明!

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



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