forEach
forEach() 方法按升序为数组中含有效值的每一项执行一次 callback 函数,那些已删除或者未初始化的项将被跳过(例如在稀疏数组上)。
参数:
1.可依次向 callback 函数传入三个参数:
- 数组当前项的值
- 数组当前项的索引
- 数组对象本身
2.如果 thisArg 参数有值,则每次 callback 函数被调用时,this 都会指向 thisArg 参数。如果省略了 thisArg 参数,或者其值为 null 或 undefined,this 则指向全局对象。按照函数观察到 this 的常用规则,callback 函数最终可观察到 this 值。
注意事项:
- 1.forEach() 遍历的范围在第一次调用 callback 前就会确定。调用 forEach 后添加到数组中的项不会被 callback 访问到。
var arr = [1, 2, 3, 4, 5];
let count = 0
arr.forEach(function (item,index,arr) {
count++
if (item === 2) {
arr.push(8)
}
console.log(item);
})
console.log('count的值' + count)
console.log(arr)
- 2.如果已经存在的值被改变,则传递给 callback 的值是 forEach() 遍历到他们那一刻的值。已删除的项不会被遍历到。如果已访问的元素在迭代时被删除了(例如使用 shift()),之后的元素将被跳过.
var words = ['one', 'two', 'three', 'four'];
words.forEach(function(word) {
console.log(word);
if (word === 'two') {
words.shift();>
}
});
// one
// two
// four
下面的例子会输出 “one”, “two”, “four”。当到达包含值 “two” 的项时,整个数组的第一个项被移除了,这导致所有剩下的项上移一个位置。因为元素 “four” 正位于在数组更前的位置,所以 “three” 会被跳过。 forEach() 不会在迭代之前创建数组的副本。
- 3.它总是返回 undefined 值,并且不可链式调用。其典型用例是在一个调用链的最后执行副作用(side effects,函数式编程上,指函数进行 返回结果值 以外的操作)。
let nums = [1, 2, 3];
nums.forEach((item, index) => {
return;//无效
})
1.使用try监视代码块,在需要中断的地方抛出异常。
2.官方推荐方法(替换方法):用every和some替代forEach函数。every在碰到return false的时候,中止循环。some在碰到return ture的时候,中止循环
- 4.即 forEach 不会直接改变调用它的对象,但是那个对象可能会被 callback 函数改变。
- 5.不对未初始化的值进行任何操作(稀疏数组)
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
- 如果使用 promise 或 async 函数作为 forEach() 等类似方法的 callback 参数,最好对造成的执行顺序影响多加考虑,否则容易出现错误。
let ratings = [5, 4, 5];
let sum = 0;
let sumFunction = async function (a, b) {
return a + b;
}
ratings.forEach(async function(rating) {
sum = await sumFunction(sum, rating);
})
console.log(sum);
// Expected output: 14
// Actual output: 0
实现一个foreach
Array.prototype.for_Each = function (fn, context) {
context = context || this;
var i = 0,
len = this.length; //this为调用for_Each 的数组,而不是context
console.log(this)
for (; i < len; i++) {
fn.call(context, this[i], i, this); //注意回调函数可以改变this为第二个参数 context
}
}