forEach every some filter map reduce reduceRight以及es6新增的entries find findIndex keys values 都是基于es6,不会改变自身的办法一共有12个。
forEach 方法指定数组的每项元素都执行一次传入函数,返回值为undefined.
语法:arr.forEach(fn, thisArg)
fn 标识在数组每一项上执行的函数,接收三个参数。
- value 当前正在被处理的元素的值
- index 当前正在被处理元素的索引
- array 当前数组的本身
thisArg 可选,用来当作fn函数内的this对象
forEach 将为数组中的每一项执行一次fn函数,那些已删除,新增或者从未赋值的项将被跳过(但不包括值为undefined的项)
遍历过程中,fn会被传入上述三个参数
1 | var arr =[1,2,3,4] |
同样也可以用Array.prototype.forEach.call()1
2
3
4
5var o = {0:1, 1:3, 2:5, length:3};
Array.prototype.forEach.call(o,function(value, index, obj){
console.log(value,index,obj);
obj[index] = value * value;
},o);
如果不支持可以用polyfill
1 | if (!Array.prototype.forEach) { |
every 传入的函数测试所有的元素,只要其中有一个函数返回值为false,那么该办法的结果为false;如果全部返回true,那么该办法的结果才返回true,因为every存在如下规律:
- 若需检测数组中所有存在元素是否大于10(即value > 10),那么需要在传入的函数中return ‘true’返回值,同时整个方法结果为true才表示数组存在的元素满足条件 (即数组中的value 都大于10,那么就算满足条件,返回true)
- 反之 若需要检测数组中存在的元素是否有不满足的大于10的,返回 ‘false’
语法同forEach 相同,
1 | var arr = [11,12,13,14,15,16] |
同样也适用Array.prototype.every.call()
1 | var o = {0:10, 1:8, 2:25, length:3}; |
如果不支持,可以用ployfill
1 | if (!Array.prototype.every) |
some 跟every相反,使用some检测数组元素时,只要有一个函数返回值为true,则该方法返回true,如果全部都返回false,则该方法才返回false,
- 若需检测数组中存在的元素是否有一个元素或多个元素大于10(即value > 10),那么我们需要在传入的函数中 return ‘true’,则some返回true,反之所有函数的返回false,则some返回false
1 | var arr = [10,1,2,3,4] |
Array.prototype.come.call()同every一样,参照every的写法。
如果不支持的话可以用polyfill:
1 | if (!Array.prototype.some) |
filter 使用传入的函数测试所有元素,并返回所有通过测试的元素组成新的数组,他就好比一个过滤器,筛选掉不符合条件的元素。
语法:arr.filter(fn, thisArg)
1 | var arr = [10,3,20,12,13,40] |
Array.prototype.filter.call()写法同every一样,polyfill:
1 | if (!Array.prototype.filter) |
map 遍历数组元素,使用传入函数处理每一个元素,并返回函数的返回值组成新的数组。
语法:
let new_array = arr.map(function callback(currentValue, index, array) {
// Return element for new_array
}[, thisArg])
- map方法会给数组中的每个元素都按顺序调用一次callback函数,callback每次执行后返回的返回值(包括undefined)组合成新的数组,callback函数只会在有有值的索引上被调用,那些从来没被赋过值或者使用delete删除的索引则不会使用。
- callback 函数会被自动传入三个参数,数组元素,数组索引,原数组本身
- thisArg 参数有值,则每次callback函数被调用的时候,this都会指向这个thisArg参数上的这个对象,如果省略了thisArg参数,或者赋值为null或undefined,则this指向全局对象。
- map在执行的的时候不会修改原数组本身 (也可以在callback执行时改变原数组元素)
- 使用 map 方法处理数组时,数组元素的范围是在 callback 方法第一次调用之前就已经确定了。在 map 方法执行的过程中:原数组中新增加的元素将不会被 callback 访问到;若已经存在的元素被改变或删除了,则它们的传递到 callback 的值是 map 方法遍历到它们的那一时刻的值;而被删除的元素将不会被访问到。
1 | var obj = [{key:1,value:10},{key:2,value:20},{key:3,value:30}] |
Array.prototype.map.cal()使用:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15var a = Array.prototype.map.call('hello word',function(value){
console.log(value)
})
h
e
l
l
o
w
o
r
d
遍历querySelectorAll()所有集合1
2
3
4var el = document.querySelectorAll('div')
Array.prototype.map.call(el,function(value){
console.log(value)
})
返回字符串1
2
3
4
5
6var str = '12345';
Array.prototype.map.call(str, function(x) {
return x;
}).reverse().join('');
// 输出: '54321'
MDN上有这么描述map的话:
通常情况下,map 方法中的 callback 函数只需要接受一个参数,就是正在被遍历的数组元素本身。但这并不意味着 map 只给 callback 传了一个参数。这个思维惯性可能会让我们犯一个很容易犯的错误。
1 | // 下面的语句返回什么呢: |
reduce 接收一个方法作为累加器,数组中的每个值(从左至右)开始合并,最终一个值。
语法:arr.reduce(callback, initialValue)
callback 每次执行数组中每个值的函数,包含四个参数:
- previousValue 上一次调用回调时累计的返回的值,或者是提供的初始值
- value 数组中当前被处理元素的值
- index 当前元素在数组中的索引
- array 原数组自身
initialValue 指定第一次调用fn的第一个参数,如果没有提供初始值,则使用数组的第一个元素的值,。
当callback第一次执行时:
- 如果initialValue 在调用reduce时被提供,那么第一个previousValue 将等于initialValue,此时item等于数组中的第一个值
- 如果 initialValue 未被提供,那么 previousVaule 等于数组中的第一个值,item 等于数组中的第二个值。此时如果数组为空,那么将抛出 TypeError。
- 如果数组仅有一个元素,并且没有提供 initialValue,或提供了 initialValue 但数组为空,那么fn不会被执行,数组的唯一值将被返回。
计算1到900的和1
2
3
4
5
6
7
8
9
10
11var arr = []
for(var i=0;i<=1000;i++){
arr.push(i)
if(i == 900){
var arr2 = arr.reduce(function(sum,value){
return sum+value
})
}
}
console.log(arr2)
// 405450
把数组的[1,2,3,4,5]转换成整数的123451
2
3
4
5var num = [1,2,3,4,5].reduce(function(x,y){
return x.toString() + y
})
console.log(num)
// 12345
数组去除重复1
2
3
4
5
6
7
8
9var arr = [1,2,3,2,1,33,3,2,1]
var arr2 = arr.sort().reduce(function(init,current){
if(init.length === 0 || init[init.length-1]!== current){
init.push(current);
}
return init;
},[])
console.log(arr2)
// [1, 2, 3, 33]
1 | var array = [1, 2, 3, 4]; |
以上回调被执行了4次,每次的参数和返回:
|callback |previousValue |currentValue |index |array |return |value|
|—|—|—|—|—|—|—|
|第1次 |1 |1 |1 |[1,2,3,4] 1|
|第2次 |1 |2 |2 |[1,2,3,4] 2|
|第3次 |2 |3 |3 |[1,2,3,4] 6|
|第4次 |6 |4 |4 |[1,2,3,4] 24|
Array.prototype.reduce.call()写法参照every,如果不支持reduce,可以用polyfill:
1 | if (!Array.prototype.reduce) { |
reduceRight 方法与reduce写法一样,与reduce不同的是,reduceRight是从右至左开始合并,最终返回一个值,与reduce的执行方向相反,其它完全一致,写法参考reduce
polyfill:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29if ('function' !== typeof Array.prototype.reduceRight) {
Array.prototype.reduceRight = function(callback /*, initialValue*/) {
;
if (null === this || 'undefined' === typeof this) {
throw new TypeError('Array.prototype.reduce called on null or undefined');
}
if ('function' !== typeof callback) {
throw new TypeError(callback + ' is not a function');
}
var t = Object(this), len = t.length >>> 0, k = len - 1, value;
if (arguments.length >= 2) {
value = arguments[1];
} else {
while (k >= 0 && !(k in t)) {
k--;
}
if (k < 0) {
throw new TypeError('Reduce of empty array with no initial value');
}
value = t[k--];
}
for (; k >= 0; k--) {
if (k in t) {
value = callback(value, t[k], k, t);
}
}
return value;
};
}
entries 基于ECMAScript2015(es6)规范,返回一个数组迭代器对象,该对象包括数组中每个索引的键值对,手动循环对象的属性值可以输出相应的属性位置的值。
1 | var arr = [1,2,3,4] |
也可以使用:Array.prototype.entries.call()
1 | var o = {0:"a", 1:"b", 2:"c", length:3}; |
find 基于ECMAScript2015(es6)规范,返回数组中第一个满足条件的元素的值,如果数组为空或是稀疏数组 则返回undefined,find不会改变原来的数组。
语法:arr.find(callback[, thisArg])
- callback 执行数组的每一个值的函数,接收3个参数
- element 当前遍历到的元素
- index 当前遍历到的索引
- array 数组本身
- thisArg 可指定callback的this参数
查找满足条件的数组对象1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16var inventory = [
{value: 'js', name: 0},
{value: 'css', name: 1},
{value: 'jq', name: 2}
];
function findCherries(fruit) {
return fruit.value === 'css';
}
function findIndexCher(isValue){
return isValue === 'vue'
}
console.log(inventory.find(findCherries)); // {value: "css", name: 1}
console.log(inventory.find(findIndexCher)); // undefined
Array.prototype.find.call()写法与上面类似,不在阐述,
polyfill:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43if (!Array.prototype.find) {
Object.defineProperty(Array.prototype, 'find', {
value: function(predicate) {
// 1. Let O be ? ToObject(this value).
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
// 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
var thisArg = arguments[1];
// 5. Let k be 0.
var k = 0;
// 6. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kValue be ? Get(O, Pk).
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
// d. If testResult is true, return kValue.
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {
return kValue;
}
// e. Increase k by 1.
k++;
}
// 7. Return undefined.
return undefined;
}
});
}
findIndex 基于ECMASscript2015(es6)规范,他返回数组中第一个满足条件的元素的索引,如果没有则返回-1,写法与find相同。
1 | var inventory = [ |
Array.prototype.findIndex.call()写法与上面类似,不在阐述,
polyfil:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43if (!Array.prototype.findIndex) {
Object.defineProperty(Array.prototype, 'findIndex', {
value: function(predicate) {
// 1. Let O be ? ToObject(this value).
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
// 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
var thisArg = arguments[1];
// 5. Let k be 0.
var k = 0;
// 6. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kValue be ? Get(O, Pk).
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
// d. If testResult is true, return k.
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {
return k;
}
// e. Increase k by 1.
k++;
}
// 7. Return -1.
return -1;
}
});
}
keys 基于ECMAScript2015(es6)规范,返回一个数组索引的迭代器
1 | var arr = ['js','css','jq'] |
在稀疏数组中使用keys也会 包含那些没有值的对应索引,如下:
1 | var array = ["abc", , "xyz"]; |
用keys快速生成0到10的新数组1
2[...Array(10).keys()]; // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[...new Array(10).keys()]; // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Array.prototype.keys.call()写法与上面类似,不在阐述,
values 基于ECMAScript2015(es6)规范,返回一个数组迭代器对象,该对象包含数组中每个索引的值。用法与entries相同。
1 | var array = ["abc", "xyz"]; |
Symbol.iterator 该方法基于ECMAScript 2015(ES6)规范,同 values 方法功能相同。
1 | var array = ["abc", "xyz"]; |
Array.prototype[Symbol.iterator].call()写法与上面类似,不在阐述
参考资料1:http://louiszhai.github.io/2017/04/28/array
参考资料2:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array