forEach的详解
1、1输出了多少次?
let arr = [1, 2];
arr.forEach((item, index) => {
arr.splice(index, 1);
console.log(1); //输出几次?
});
console.log(arr)
结果:
1
Array [2]
2、this的回调指向
arr.forEach(function(self,index,arr){},this);
self:数组当前遍历的元素,默认从左往右依次获取数组元素。
index:数组当前元素的索引,第一个元素索引为0,依次类推。
arr:当前遍历的数组。
this:回调函数中this指向。
let arr1 = [1, 2, 3, 4];
let obj = {
a: 1
};
arr1.forEach(function (self, index, arr) {
console.log(`当前元素为${self}索引为${index},属于数组${arr}`);
//做个简单计算
console.log(self + this.a);
}, obj)
“当前元素为1索引为0,属于数组1,2,3,4”
2
“当前元素为2索引为1,属于数组1,2,3,4”
3
“当前元素为3索引为2,属于数组1,2,3,4”
4
“当前元素为4索引为3,属于数组1,2,3,4”
5
通俗理解,this指向的是上面所提供的obj对象,而arr则遍历的是当前的数组。
3、可以做到去重
let arr1 = [1, 2, 1, 3, 1];
let arr2 = [];
arr1.forEach(function (self, index, arr) {
arr.indexOf(self) === index ? arr2.push(self) : null;
});
console.log(arr2);
[1,2,3]
正如第二条所提的arr是指当前所遍历的对象,所在indexof的过程下都会可以做到数组去重的效果。
注意:
1.forEach不支持break
2.forEach中使用return无效
3.forEach删除自身元素index不会被重置
arr.forEach((item, index) => {
arr.splice(index, 1);
console.log(1);
//这里隐性让index自增加1
index++;
});
当第一次遍历结束,此时数组为[2]而index变成了1,此时数组最大索引只是0,不满足条件,所以跳出了循环。
有没有什么办法让此时的forEach不跳出循环呢,当然有,使用ES6的拓展运算符
。
[...arr].forEach((item, index) => {
arr.splice(index, 1);
console.log(1);
});
通过拓展运算符重置数组arr,达到不跳出循环的目的,你会发现内部确实执行了两次,很遗憾的是index依旧没被重置,所以数组arr还是无法在遍历的同时删空自己。
4、数组遍历并删除自身
for循环:
let arr = [1, 2, 1],
i = 0,
length = arr.length;
for (; i < length; i++) {
// 删除数组中所有的1
if (arr[i] === 1) {
arr.splice(i, 1);
//重置i,否则i会跳一位
i--;
};
};
console.log(arr);//[2]
filter过滤方法:
var arr1 = arr.filter((index) => {
return index !== 1;
});
console.log(arr1); //[2]
forEach遍历:
arr.slice().reverse().forEach(function (item, index, arr1) {
if (item === 1) {
arr.splice(arr1.length - 1 - index, 1);
}
});
console.log(arr);//[2]