forEach使用的注意点

不支持异步函数


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

forEach不会改变原数组

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值