ECMAScript5(ES5)标准中扩展的数组Array方法
迭代forEach()
这是ES5数组方法中最基本的一个了
也非常的简单,就是遍历、循环
我们传统的数组循环方法是这样的
var arr = [1, 2, 3, 4, 5];
for(var i = 0, len = arr.length; i < len; i++){
console.log(arr[i]);
}
//1 2 3 4 5
forEach()第一个参数是一个回调函数
对于数组的每一个元素,它都会执行这个回调函数
而且这个回调函数有默认的参数
分别是数组元素、数组索引、数组引用
数组引用就是数组自身的引用
(这个参数顺序与下面的map()、filter()、some()、every()都是一样的)
看下面这个例子就明白了
['a', 'b', 'c', 'd', 'e'].forEach(console.log);
控制台打印如下
我们也可以把这个写的更直白一些
['a', 'b', 'c', 'd', 'e'].forEach(function(value, index, arr){
console.log(value, index, arr);
});
- 1
- 2
- 3
所以我们一般就是这样使用这个方法的
[].forEach(function(value, index, arr){
...
});
不过要特别注意,这个回调函数中参数的顺序与jQuery是不同的
下面是jQuery中的each()方法使用
$.each(function(index, value, arr){
...
});
forEach()方法中还有一个可选的上下文参数
就是回调函数中的this指向
(map()、filter()、some()、every()同样有)
举个例子
var group = {
member: ['a1', 'a2', 'b1', 'b2', 'c1', 'c2'],
isActive: function(member){
return /1$/.test(member);
},
active: function(member){
if(this.isActive(member)){
console.log(member + '是活跃成员');
}
}
}
group.member.forEach(group.active, group);
在这个例子中,就必须手动将回调函数的this设置为group
否则的话,将会是window对象(浏览器中)
(严格模式下是undefined)
映射map()
映射方法map()的参数与循环方法forEach()是一样的
一个回调函数和一个可选的上下文参数
包括回调函数的参数顺序也一样(肯定一样)
所谓映射不难理解,在我们的数学中都学过
类似于C++的STL标准库中的map
var arr = [1, 2, 3, 4, 5];
var mapArr = arr.map(function(value){
return value*value;
});
console.log(mapArr); //[1, 4, 9, 16, 25]
这个例子中将一个数组中所有元素求平方得到一个新数组
不过既然要使用映射函数map()
就必须要用return返回值
返回的值就是新数组中映射的值
(否则就相当于使用了forEach(),还返回了一个全是undefined的数组)
至于上下文参数就不多做解释了
上面在forEach()中已经说过了
筛选filter()
用法与map()相似
同样返回一个新数组(同样有一个可选的上下文参数)
不过是过滤掉“不合格”的元素
如果在回调函数中返回true,那么就留下来
返回false,就扔掉
var arr = [5, 20, 24, 66, 40, 49, 60];
var newArr = arr.filter(function(value){
return value % 10 == 0;
});
console.log(newArr); //[20, 40, 60]
我筛选出了数组中整十的数字
再举个例子,筛选奇数索引(相对于我们来说的奇数索引)
var arr = [5, 20, 24, 66, 40, 49, 60];
var newArr = arr.filter(function(value, index){
return index % 2 == 0;
});
console.log(newArr); //[5, 24, 40, 60]
这里要注意
返回的值不必是严格的布尔值
返回值可以通过类型转换转化为布尔值进行判断
存在满足判断some()
这个方法返回布尔值
只要有至少一个满足条件就返回true
(至少一个返回true)
否则返回false
var arr = [5, 20, 24, 66, 40, 49, 60];
var flag = arr.some(function(value){
return value % 10 == 0;
});
console.log(flag); //true
由于存在整十的元素,所以结果返回true
var arr = [5, 20, 24, 66, 40, 49, 60];
var flag = arr.some(function(value){
return value % 100 == 0;
});
console.log(flag); //false
由于不存在整百的元素,所以结果返回false
全部满足判断every()
与上面的some()是好兄弟
它更加严格
必须全部满足条件才会返回true
(全部返回true)
var arr = [5, 20, 24, 66, 40, 49, 60];
var flag = arr.every(function(value){
return value % 1 == 0;
});
console.log(flag); //true
由于对于数组的全部元素
都是1的倍数
所以返回true
索引查寻indexOf()与lastIndexOf()
早在ES3字符串就存在方法indexOf()方法
它们功能是一样的
第一个参数表示你要查找的元素
第二个参数可选,表示你要从第几位开始查找(索引)
第二个参数不填写就是默认从头开始查找
返回第一个找到的索引位
var arr = [10, 20, 30, 40, 50, 60];
var index = arr.indexOf(30);
console.log(index); //2
最终找到了30所在的索引位置2
var arr = [10, 20, 30, 40, 50, 60];
var index = arr.indexOf(30, 3);
console.log(index); //-1
现在加一个参数3
表示从索引3开始查找
最终没有查找到元素,结果返回-1
lastIndexOf()是从后往前进行查找
var arr = [10, 20, 30, 40, 50, 60];
var index = arr.lastIndexOf(30, 3);
console.log(index); //2
修改为lastIndexOf()方法后
由于是从后向前查找,可以得出结果
浓缩reduce()与reduceRight()
不知道该怎样描述这两个方法
觉得“浓缩”这层意思更符合它的功能
它有点类似于递归
它的作用就是不断的减少数组元素,最终的到一个结果
这个方法稍微复杂一些
它的第一个参数同样是一个回调函数;第二个参数可选,表示初始值
但是它回调函数的参数与上面的有些不同
分别是之前值、当前值、数组索引、数组引用
(看了下面就明白了)
先来看一下没有初始值的情况
计算数组元素的积
(pre表示previous之前值,cur表示current当前值)
var arr = [1, 2, 3, 4];
var result = arr.reduce(function(pre, cur){
return pre * cur;
});
console.log(result); //24
没有初始值时,数组的第一个元素就是初始值
那么第一次走回调函数
之前值(初始值)是1,当前值是2
回调函数返回乘积结果是2
第二次走回调函数的时候
之前值是2(上一次的返回结果),当前值是3
于是以此类推,最终得到了数组元素的乘积
//伪代码
//第一次迭代:
pre = 1, cur = 2, return 1 * 2 = 2
//第二次迭代:
pre = 2, cur = 3, return 2 * 3 = 6
//第三次迭代:
pre = 6, cur = 4, return 6 * 4 = 24
//结果
return 24
有了初始值,那么第一次走回调函数时
指定的初始值就是之前值
数组的首个元素就是当前值
var arr = [1, 2, 3, 4];
var result = arr.reduce(function(pre, cur){
return pre * cur;
}, 10); <--
console.log(result); //240
这里我指定了初始值10
于是结果发生了改变
//伪代码
//初始值设置
pre = initialValue = 10
//第一次迭代:
pre = 10, cur = 1, return 10 * 1 = 10
//第二次迭代:
pre = 10, cur = 2, return 10 * 2 = 20
//第三次迭代:
pre = 20, cur = 3, return 20 * 3 = 60
//第四次迭代:
pre = 60, cur = 4, return 60 * 4 = 240
//结果
return 240
这也相当于下面的代码
var arr = [10, 1, 2, 3, 4]; <--
var result = arr.reduce(function(pre, cur){
return pre * cur;
});
console.log(result); //240
reduceRight()便是从右向左“浓缩”
用法和reduce()是一样的
下面的方法是利用这个方法计算 (2^3)^4
var arr = [4, 3, 2];
var result = arr.reduceRight(function(pre, cur){
return Math.pow(pre, cur);
});
console.log(result); //4096
- 迭代 array.forEach(callback[, thisObject]);
- 映射 array.map(callback[, thisObject]);
- 筛选 array.filter(callback[, thisObject]);
- 存在 array.some(callback[, thisObject]);
- 全部 array.every(callback[, thisObject]);
- 索引 array.indexOf(searchElement[, fromIndex]);
- 索引 array.lastIndexOf(searchElement[, fromIndex]);
- 浓缩 array.reduce(callback[, initialValue]);
- 浓缩 array.reduceRight(callback[, initialValue]);
其中forEach()、map()、filter()、some()、every()、indexOf()、lastIndexOf()
的callback参数分别为value、index、array
reduce()和reduceRight()
的callback参数分别为previous、current、index、array