语法

arr.forEach(callback(currentValue [, index [, array]])[, thisArg])

参数

callback
   为数组中每个元素执行的函数,该函数接收一至三个参数:
currentValue
   数组中正在处理的当前元素。
index (可选)
    数组中正在处理的当前元素的索引。
array (可选)
  forEach() 方法正在操作的数组。
thisArg (可选)
 可选参数。当执行回调函数 callback 时,用作 this 的值。

返回值

undefined。

描述

   forEach() 方法按升序为数组中含有效值的每一项执行一次 callback 函数,那些已删除或者未初始化的项将被跳过(例如在稀疏数组上)。
  可依次向 callback 函数传入三个参数:
    1、数组当前项的值
    2、数组当前项的索引
    3、数组对象本身
  如果 thisArg 参数有值,则每次 callback 函数被调用时,this 都会指向 thisArg 参数。如果省略了 thisArg 参数,或者其值为 null 或 undefined,this 则指向全局对象。按照函数观察到 this 的常用规则,callback 函数最终可观察到 this 值。
  forEach() 遍历的范围在第一次调用 callback 前就会确定。调用 forEach 后添加到数组中的项不会被 callback 访问到。如果已经存在的值被改变,则传递给 callback 的值是 forEach() 遍历到他们那一刻的值。已删除的项不会被遍历到。如果已访问的元素在迭代时被删除了(例如使用 shift()),之后的元素将被跳过
  forEach() 为每个数组元素执行一次 callback 函数;与 map() 或者 reduce() 不同的是,它总是返回 undefined 值,并且不可链式调用。其典型用例是在一个调用链的最后执行副作用(side effects,函数式编程上,指函数进行 返回结果值 以外的操作)。
  forEach() 被调用时,不会改变原数组,也就是调用它的数组(尽管 callback 函数在被调用时可能会改变原数组)。(译注:此处说法可能不够明确,具体可参考EMCA语言规范:’forEach does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.’,即 forEach 不会直接改变调用它的对象,但是那个对象可能会被 callback 函数改变。)

注意: 除了抛出异常以外,没有办法中止或跳出 forEach() 循环。如果你需要中止或跳出循环,forEach() 方法不是应当使用的工具。

例子:

3 和 7 之间空缺的数组单元未被 forEach() 调用 callback 函数,或进行任何其他操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const arraySparse = [1,3,,7];
let numCallbackRuns = 0;

arraySparse.forEach(function(element){
console.log(element);
numCallbackRuns++;
});

console.log("numCallbackRuns: ", numCallbackRuns);

// 1
// 3
// 7
// numCallbackRuns: 3

将 for 循环转换为 forEach
1
2
3
4
5
6
7
8
9
10
11
12
const items = ['item1', 'item2', 'item3'];
const copy = [];

// before
for (let i=0; i<items.length; i++) {
copy.push(items[i]);
}

// after
items.forEach(function(item){
copy.push(item);
});

打印出数组的内容
1
2
3
4
5
6
7
8
9
10
function logArrayElements(element, index, array) {
console.log('a[' + index + '] = ' + element);
}

// 注意索引 2 被跳过了,因为在数组的这个位置没有项
[2, 5, , 9].forEach(logArrayElements);
// logs:
// a[0] = 2
// a[1] = 5
// a[3] = 9

如果数组在迭代时被修改了,则其他元素会被跳过。

  下面的例子会输出 “one”, “two”, “four”。当到达包含值 “two” 的项时,整个数组的第一个项被移除了,这导致所有剩下的项上移一个位置。因为元素 “four” 正位于在数组更前的位置,所以 “three” 会被跳过。 forEach() 不会在迭代之前创建数组的副本。

1
2
3
4
5
6
7
8
9
10
var words = ['one', 'two', 'three', 'four'];
words.forEach(function(word) {
console.log(word);
if (word === 'two') {
words.shift();
}
});
// one
// two
// four


愿你的坚持终有收获。