参考文章:ES5中新增的Array方法详细说明
forEach
方法与map方法很相似,也就是调用数组的每个元素
,并将元素传递给回调函数
。
也就是对于数组中出现的每个元素,forEach 方法都会调用 callbackfn 函数一次。
但是,forEach
方法不返回值
,只用来操作数据
。 map
方法必须要return返回值。 这就是说,如果数组遍历的目的是为了得到返回值,那么使用map方法,否则使用forEach方法。
forEach 方法不直接修改
原始数组。
语法
array.forEach(function(value, index, arr), thisValue)
参数 | 描述 |
---|---|
value | 必需。当前元素 |
index | 可选。当前元素的索引值。 |
arr | 可选。当前元素所属的数组对象。 |
thisValue | 可选。绑定参数函数的this变量。 |
回调函数语法
[1, 2, 3, 4].forEach(function (value, index, array) {
console.log(value, index, array)
});
// 结果:
// 1, 0, [1, 2, 3, 4]
// 2, 1, [1, 2, 3, 4]
// 3, 2, [1, 2, 3, 4]
// 4, 3, [1, 2, 3, 4]
对比jQuery中的$.each方法:
$.each([], function(index, value, array) {
// ...
});
会发现,第1个和第2个参数正好是相反的,大家要注意了,不要记错了。后面类似的方法,例如$.map也是如此。
现在看稍显完整的例子,数组求和:
var sum = 0;
[1, 2, 3, 4].forEach(function (item, index, array) {
console.log(array[index] == item); // true
sum += item;
});
alert(sum); // 10
更进一步,forEach除了接受一个必须
的回调函数参数,还可以接受一个可选
的上下文参数(改变回调函数里面的this
指向)。
array.forEach(callback,[thisObject])
- 下面代码中,空数组out是forEach方法的第二个参数,结果,回调函数内部的this关键字就指向out。
var out = [];
[1, 2, 3].forEach(function(elem) {
this.push(elem * elem);
}, out);
out // [1, 4, 9]
// out代替this
- 如果这第2个可选参数不指定,则
Window
会传递给this
,严格模式下为undefined
[1, 2, 3].forEach(function(elem) {
console.log(this);
});
//Window
//Window
//Window
注意,forEach方法无法中断执行,总是会将所有成员遍历完。如果希望符合某种条件时,就中断遍历,要使用for循环。
var arr = [1, 2, 3];
for (var i = 0; i < arr.length; i++) {
if (arr[i] === 2) break;
console.log(arr[i]);
}
// 1
上面代码中,执行到数组的第二个成员时,就会中断执行。forEach方法做不到这一点
。
forEach方法也会跳过数组的空位
var log = function (n) {
console.log(n + 1);
};
[1, undefined, 2].forEach(log)
// 2
// NaN
// 3
[1, null, 2].forEach(log)
// 2
// 1
// 3
[1, , 2].forEach(log)
// 2
// 3
上面代码中,forEach方法不会跳过undefined和null,但会<font color=red size=4>跳过空位</font>。
- 注意:JavaScript以NaN的形式输出Number.NaN。说明某些算术运算的结果不是数字。NaN与其他数值进行比较的结果总是不相等的,包括它自身在内。因此,不能与Number.NaN比较来检测一个值是不是数字,而只能调用 isNaN() 来比较。
综上全部规则,我们就可以对不支持foreach的IE6-IE8进行仿真扩展了,如下代码:
// 对于古董浏览器,如IE6-IE8
if (typeof Array.prototype.forEach != "function") {
Array.prototype.forEach = function (fn, context) {
for (var k = 0, length = this.length; k < length; k++) {
//Object.prototype.hasOwnProperty.call(this, k)意思是将hasOwnProperty方法的原始定义放到this对象上执行
if (typeof fn === "function" && Object.prototype.hasOwnProperty.call(this, k)) {
fn.call(context, this[k], k, this);
}
}
};
}
网友评论