摘要:正文和中新增的的數(shù)組迭代方法如下其中,是新增的,其余都是新增的。指數(shù)組后,返回過濾后的新數(shù)組。它的參數(shù)跟方法是一樣的所有數(shù)組成員依次執(zhí)行回調(diào)函數(shù),直到找出第一個(gè)返回值為的成員,然后返回該成員。
前言
ES5和ES6中新增了不少東西,對(duì)于數(shù)組而言,新增了不少迭代方法,讓我們可以拋棄for循環(huán),更方便的寫JS代碼。
正文ES5和ES6中新增的的數(shù)組迭代方法如下:
forEach
map
filter
some
every
reduce / reduceRight
find / findIndex
其中,find / findIndex是ES6新增的,其余都是ES5新增的。所以這些方法對(duì)低版本IE都不兼容。
接下來我們看看這些方法如何使用并在低版本IE進(jìn)行兼容。
forEach方法是這些方法里面最基本的一個(gè)方法,它的作用是對(duì)數(shù)組的每個(gè)元素執(zhí)行一次提供的函數(shù)。
例如:
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函數(shù)會(huì)被依次傳入三個(gè)參數(shù):
數(shù)組當(dāng)前項(xiàng)的值
數(shù)組當(dāng)前項(xiàng)的索引
數(shù)組對(duì)象本身
forEach方法還可以傳入第二個(gè)參數(shù),這個(gè)參數(shù)是可選的。如果給forEach傳遞了第二個(gè)參數(shù),callback函數(shù)里的this將指向這個(gè)參數(shù)。如果沒有傳入第二個(gè)參數(shù),則this指向全局對(duì)象(在瀏覽器是為window),嚴(yán)格模式下是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寫一個(gè)稍顯完整的例子了,數(shù)組求和:
var sum = 0; [1, 2, 3].forEach(function (element, index, array) { console.log(array[index] == element); // true sum += item; }); console.log(sum); // 6
最后我們對(duì)低版本IE進(jìn)行一下拓展,是這個(gè)方法就有更好的兼容性,代碼如下:
Array.prototype.forEach = Array.prototype.forEach || function(fn, context){ for (var k = 0, length = this.length; k < length; k++) { if (typeof fn === "function" && Object.prototype.hasOwnProperty.call(this, k)) { fn.call(context, this[k], k, this); } } }map
map方法的作用就是將原數(shù)組按照一定的規(guī)則映射成一個(gè)新的數(shù)組。再將其返回,是返回一個(gè)新的數(shù)組,而不是將原數(shù)組直接改變。使用方法和參數(shù)都跟forEach相似。
下面是一個(gè)數(shù)值求平方的例子:
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]
最后我們對(duì)map方法進(jìn)行一下拓展:
Array.prototype.map = Array.prototype.map || function (fn, context) { var arr = []; if (typeof fn === "function") { for (var k = 0, length = this.length; k < length; k++) { arr.push(fn.call(context, this[k], k, this)); } } return arr; };filter
filter為“過濾”、“篩選”的意思。指數(shù)組filter后,返回過濾后的新數(shù)組。用法和參數(shù)跟map差不多。
與map方法不同的是,filter方法的callback函數(shù)需要返回弱等于true或false的值。如果為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]
下面是對(duì)filter方法的拓展:
Array.prototype.filter = Array.prototype.filter || function (fn, context) { var arr = []; if (typeof fn === "function") { for (var k = 0, length = this.length; k < length; k++) { fn.call(context, this[k], k, this) && arr.push(this[k]); } } return arr; };some
some方法是只要數(shù)組中的某個(gè)值,符合你給定的判斷條件就返回true;否則,返回false。用法和參數(shù)跟前面的方法一樣。
例如:
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
下面是some方法的拓展:
Array.prototype.some = Array.prototype.some || function (fn, context) { var passed = false; if (typeof fn === "function") { for (var k = 0, length = this.length; k < length; k++) { if (passed === true) break; passed = !!fn.call(context, this[k], k, this); } } return passed; };every
every方法與some方法相對(duì),every方法是數(shù)組中的所有值都符合你給定的判斷條件的時(shí)候才會(huì)返回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
every方法拓展如下:
Array.prototype.every = Array.prototype.every || function (fn, context) { var passed = true; if (typeof fn === "function") { for (var k = 0, length = this.length; k < length; k++) { if (passed === false) break; passed = !!fn.call(context, this[k], k, this); } } return passed; };reduce / reduceRight
reduce / reduceRight 方法比上面的幾種方法要復(fù)雜一些;它的語法如下:
array.reduce(callback,[initialValue])
其中callback可以依次接受四個(gè)參數(shù):
accumulator上一次調(diào)用回調(diào)返回的值,或者是提供的初始值(initialValue)
currentValue數(shù)組中正在處理的元素
currentIndex數(shù)組中正在處理的元素索引,如果提供了initialValue ,從0開始;否則從1開始。
array數(shù)組對(duì)象本身
reduce / reduceRight 方法中,第二個(gè)參數(shù)(initialValue)是可選的;其值用于第一次調(diào)用callback的第一個(gè)參數(shù)。
我們先來看一個(gè)例子:
var sum = [1, 2, 3].reduce(function(a, b) { return a + b; }); console.log(sum); // 6
下面我們來看看reduce是如何運(yùn)行的
例如執(zhí)行下面這段代碼:
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
從上面的輸出結(jié)果可以看出callback被調(diào)用四次,每次調(diào)用的參數(shù)和返回值如下表:
callback | accumulator | currentValue | currentIndex | array | return |
---|---|---|---|---|---|
第一次調(diào)用 | 0 | 1 | 1 | [0, 1, 2, 3, 4] | 1 |
第二次調(diào)用 | 1 | 2 | 2 | [0, 1, 2, 3, 4] | 3 |
第三次調(diào)用 | 3 | 3 | 3 | [0, 1, 2, 3, 4] | 6 |
第四次調(diào)用 | 6 | 4 | 4 | [0, 1, 2, 3, 4] | 10 |
上面是沒有傳入第二個(gè)參數(shù)(initialValue)的情況,那傳入第二個(gè)參數(shù)又是怎么樣的呢?
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
傳入第二個(gè)參數(shù)后callback調(diào)用了五次,每次調(diào)用的參數(shù)和返回值如下表:
callback | accumulator | currentValue | currentIndex | array | return |
---|---|---|---|---|---|
第一次調(diào)用 | 10 | 0 | 0 | [0, 1, 2, 3, 4] | 10 |
第二次調(diào)用 | 10 | 1 | 1 | [0, 1, 2, 3, 4] | 11 |
第三次調(diào)用 | 11 | 2 | 2 | [0, 1, 2, 3, 4] | 13 |
第四次調(diào)用 | 13 | 3 | 3 | [0, 1, 2, 3, 4] | 16 |
第五次調(diào)用 | 16 | 4 | 4 | [0, 1, 2, 3, 4] | 20 |
從上面的情況可以看出:不提供initialValue ,reduce方法會(huì)從索引1的地方開始執(zhí)行callback方法,跳過第一個(gè)索引。提供 initialValue,從索引0開始。
同時(shí),是否提供initialValue對(duì)于回調(diào)函數(shù)第一次執(zhí)行時(shí),accumulator和currentValue的取值有兩種情況:調(diào)用reduce時(shí)提供initialValue,accumulator取值為initialValue,currentValue取數(shù)組中的第一個(gè)值;沒有提供initialValue ,accumulator取數(shù)組中的第一個(gè)值,currentValue取數(shù)組中的第二個(gè)值。
reduceRight與reduce類似,不同之處在于它是從最后一個(gè)值開始計(jì)算的。
那么我們?cè)撊绾瓮卣挂粋€(gè)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方法用于找出第一個(gè)符合條件的數(shù)組成員。它的參數(shù)跟forEach方法是一樣的;所有數(shù)組成員依次執(zhí)行回調(diào)函數(shù),直到找出第一個(gè)返回值為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相似;不過它返回?cái)?shù)組中符合條件的元素的索引。如果所有成員都不符合條件,則返回-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
對(duì)于不支持find / findIndex方法的瀏覽器,我們可以自己實(shí)現(xiàn)一個(gè):
Array.prototype.find = Array.prototype.find || function (fn, context) { if (typeof fn === "function") { for (var k = 0, length = this.length; k < length; k++) { if (fn.call(context, this[k], k, this)) { return this[k]; } } } return undefined; }; Array.prototype.findIndex = Array.prototype.findIndex || function (fn, context) { if (typeof fn === "function") { for (var k = 0, length = this.length; k < length; k++) { if (fn.call(context, this[k], k, this)) { return k; } } } return -1; };最后
上面的兼容實(shí)現(xiàn)不知道對(duì)不對(duì),歡迎大家指正。
參考資料:
https://developer.mozilla.org...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/83680.html
摘要:文章內(nèi)容分兩部分前半部分為迭代器模式概念后半部分為中迭代器上半部分開始迭代器模式提供一種方法順序訪問一個(gè)聚合對(duì)象中的各個(gè)元素,而又不需要暴露該對(duì)象的內(nèi)部表示。下半部分開始的迭代器迭代器等同于遍歷器。執(zhí)行該函數(shù),會(huì)返回一個(gè)遍歷器對(duì)象。 showImg(https://segmentfault.com/img/bVbuyaZ?w=800&h=600); 文章內(nèi)容分兩部分: 前半部分為 迭...
摘要:中一共有五種數(shù)組遍歷迭代方法,它們都會(huì)對(duì)數(shù)組中每個(gè)元素執(zhí)行一些業(yè)務(wù),且都不會(huì)修改原數(shù)組,這些方法包括如果該函數(shù)任意一項(xiàng)返回,則返回,如果全部返回則最終返回如果該函數(shù)每一項(xiàng)都返回,則返回,否則返回會(huì)返回一個(gè)新數(shù)組,該數(shù)組是由滿足條件的任意項(xiàng)組 ES5中一共有五種數(shù)組遍歷(迭代)方法,它們都會(huì)對(duì)數(shù)組中每個(gè)元素執(zhí)行一些業(yè)務(wù),且都不會(huì)修改原數(shù)組,這些方法包括: 1、some() 如果該函數(shù)任意...
摘要:有兩個(gè)協(xié)議可迭代協(xié)議和迭代器協(xié)議。為了變成可迭代對(duì)象,一個(gè)對(duì)象必須實(shí)現(xiàn)或者它原型鏈的某個(gè)對(duì)象必須有一個(gè)名字是的屬性迭代器協(xié)議該迭代器協(xié)議定義了一種標(biāo)準(zhǔn)的方式來產(chǎn)生一個(gè)有限或無限序列的值。 ECMAScript 2015的幾個(gè)補(bǔ)充,并不是新的內(nèi)置或語法,而是協(xié)議。這些協(xié)議可以被任何遵循某些約定的對(duì)象來實(shí)現(xiàn)。有兩個(gè)協(xié)議:可迭代協(xié)議和迭代器協(xié)議。 可迭代協(xié)議 可迭代協(xié)議允許 JavaScri...
摘要:簡(jiǎn)單說就是一個(gè)有一個(gè)函數(shù),這個(gè)函數(shù)執(zhí)行的返回值一定是一個(gè)對(duì)象,對(duì)象有兩個(gè)屬性標(biāo)記迭代是否結(jié)束,標(biāo)記這次迭代的結(jié)果值。 引言 遍歷對(duì)象是平常工作中很常見的一個(gè)操作,幾乎是日常操作,但是遍歷對(duì)象真的是一件很容易的事情么,顯然不是的。 常用的方式 for...in for (variable in object) {...} 這個(gè)是一個(gè)很常見的用法,相信每個(gè)人順手都可以寫出來。但是這里需要主...
摘要:數(shù)據(jù)的層級(jí)意味著迭代數(shù)據(jù)結(jié)構(gòu)并提取它的數(shù)據(jù)。對(duì)于技術(shù)人而言技是單兵作戰(zhàn)能力,術(shù)則是運(yùn)用能力的方法。在前端娛樂圈,我想成為一名出色的人民藝術(shù)家。 聊聊 for of 說起 for of 相信每個(gè)寫過 JavaScript 的人都用過 for of ,平時(shí)我們用它做什么呢?大多數(shù)情況應(yīng)該就是遍歷數(shù)組了,當(dāng)然,更多時(shí)候,我們也會(huì)用 map() 或者 filer() 來遍歷一個(gè)數(shù)組。 但是就...
摘要:迭代器模式就是按照順序訪問一個(gè)對(duì)象中元素,而不用暴露該對(duì)象的內(nèi)部組成。迭代器模式就是將這個(gè)迭代實(shí)現(xiàn)從業(yè)務(wù)中分離出來。外部迭代器外部迭代器必須顯式地請(qǐng)求才會(huì)迭代下一個(gè)元素。 迭代器模式就是按照順序訪問一個(gè)對(duì)象中元素,而不用暴露該對(duì)象的內(nèi)部組成。迭代器模式就是將這個(gè)迭代實(shí)現(xiàn)從業(yè)務(wù)中分離出來。 但實(shí)際開發(fā)中我們并不將他當(dāng)成一個(gè)設(shè)計(jì)模式。 前瞻后顧 說起迭代器,想必對(duì)ES6有了解的同學(xué)應(yīng)該不會(huì)...
閱讀 1276·2021-11-17 09:33
閱讀 1745·2021-09-09 11:53
閱讀 3215·2021-09-04 16:45
閱讀 1392·2021-08-17 10:12
閱讀 2391·2019-08-30 15:55
閱讀 1782·2019-08-30 15:53
閱讀 2410·2019-08-30 15:52
閱讀 2561·2019-08-29 18:41