不支持异步函数
async function test(){
let arr = [3,2,1]
console.log('start');
arr.forEach(async item =>{
let res = await mockSync(item)
console.log(res);
})
console.log('end');
}
function mockSync(item){
return new Promise((resolve, reject) => {
setTimeout(()=>{
resolve(item)
},1000*item)
})
}
test()
// 预期结果
// start
// 3
// 2
// 1
// end
// 实际结果
// start
// end
// 1
// 2
// 3
JS中的forEach()是一个同步方法,不支持处理异步函数,若在方法中执行了异步函数,它会继续执行下一项。
无法捕获异步函数中的错误
如果异步函数在执行时抛出错误,forEach无法捕获错误。意味着即使在异步函数中抛出错误,forEach方法仍然会继续执行下去
除了抛出异常外,没有办法终止或跳出forEach循环
forEach方法不支持使用break或continue语句来跳出循环或跳过下一项,若要跳出循环或跳过某一项,应该使用for循环或者其他支持break和continue语句的方法
forEach删除自身元素,index不可被重置
在forEach中我们无法控制index的值,它只能无脑的自增直至大于数组的length跳出循环
let arr = [1,2,3,4]
arr.forEach((item,index)=>{
console.log(item);
index ++;
})
// 1
// 2
// 3
// 4
this指向问题
若forEach方法的参数是箭头函数时,this指向的是定义该箭头函数时所在的对象。
若forEach方法的参数是普通函数时,this指向的是调用该普通函数的对象
//第一种情况
const obj = {
name:'Adong',
friends:['oyfc','hzg','zmk','qwb','zdn'],
printFriends:function(){
this.friends.forEach(function(friend){//参数为普通函数
console.log(this);//window
console.log(this.name);//undefined
console.log(friend);//'oyfc','hzg','zmk','qwb','zdn'
})
}
}
//第二种情况
const obj = {
name:'Adong',
friends:['oyfc','hzg','zmk','qwb','zdn'],
printFriends:function(){
this.friends.forEach((friend)=>{//参数为箭头函数
console.log(this);//obj对象
console.log(this.name);//Adong
console.log(friend);//'oyfc','hzg','zmk','qwb','zdn'
})
}
}
//第三种情况
const obj = {
name:'Adong',
friends:['oyfc','hzg','zmk','qwb','zdn'],
printFriends:()=>{//将属性改为箭头函数
console.log(this);//window
this.friends.forEach((friend)=>{//报错,Uncaught TypeError: Cannot read properties of undefined (reading 'forEach')
console.log(this);//obj对象
console.log(this.name);//Adong
console.log(friend);//'oyfc','hzg','zmk','qwb','zdn'
})
}
}
//第四种情况
let callback = (friend,index)=>{//参数为箭头函数
console.log(this);//window
console.log(this.name);//undefined
console.log(friend);//'oyfc','hzg','zmk','qwb','zdn'
}
const obj = {
name:'Adong',
friends:['oyfc','hzg','zmk','qwb','zdn'],
printFriends:function(){
this.friends.forEach(callback)
}
}
obj.printFriends()
但是我们可以使用bind,call,apply来将参数为普通函数时的this绑定为obj,改变this指向,但是箭头函数不能,因为箭头函数不能够调用bind或apply或call,并不会起到任何效果
forEach性能比for循环低
for循环没有额外的函数调用栈和上下文
forEach的函数签名中包含了参数和上下文,所以性能会低。
会跳过已删除或者未初始化的项
例如遍历一个稀疏数组时,会自动跳过没有值的项
let arr = [1,,,4,5,,7,8]
arr.forEach((item)=>{
console.log(item);
})
// 1
// 4
// 5
// 7
// 8