前端遍历对比

1、for与forEach

for循环是自己控制循环过程。

  • 使用var声明变量时候,for和while循环性能差不多,不确定循环此时时候,建议使用while来处理。
  • 使用let声明变量时候,for循环性能要比while循环性能好。原理是没有创建全局不释放的变量。
  • forEach是es6新增的用来遍历数组方法,它的性能要比for差很多。

命令式编程和函数式编程:命令式编程是可以控制整个过程,break和continue都可以使用,受自己控制。函数式编程注重结果,执行过程被内部封装,只需要调用即可,使用起来方便,自己无法管控过程,不支持break。

  • 封装forEach函数
Array.prototype.forEach=function forEach(callback, context){
    const self=this;
    let i=0,len=self.length,context=context==null?window:context;
    for(;i<len;i++){
        typeof callback==='function'?callback.call(context, self[i], i):null;
    }
}

self.length放在外侧,防止每次循环都要访问一次self.length干扰性能。

2、for in
  • 性能最差。

  • for in是迭代(遍历)所有可枚举属性(私有属性一般都是可枚举的,length不可枚举),私有和公有(有些公有可以枚举),按照原型链一级一级查找很耗性能。

  • 问题很多不能迭代symbol属性,迭代顺序会以数字优先,公有可枚举的属性(一般是自定义)也会进行迭代。

优化for in

for(let key in obj){
  if(!obj.hasOwnPrototype(key))break;
  console.log(key);
}
// 这样可以遍历私有属性,不是私有属性不遍历,但是还是不能遍历symbol
let keys=Object.keys(obj);
keys=keys.concat(Object.getOwnPropertySymbols(obj));
keys.forEach(item=>{
  console.log(item, obj[item]);
})
// Object.keys返回私有属性key,使用Object.getOwnPropertySymbols返回symbol属性名,结合使用完成遍历。
3、for of
  • for of是遵循iterator规范,具备next方法,每次执行返回一个对象,具备value和done属性。
  • 原型拥有symbol.iterator的就可以实现for of遍历。数组/部分类数组/set/map实现了iterator规范,对象没有此规范,因此,不可以使用for of遍历。
  • for of执行过程,每次调用for of时候,以数组为例,都会访问数组的symbol.iterator函数,此函数返回一个next方法,next方法执行会拿到某一项的值,会返回done是否完成迭代),value每一次获取的值。
arr=[10, 20, 30];
arr[Symbol.iterator]=function{
    const self=this;
    let index=0;
    next(){
        if(index>self.length-1){
            return {
                done: true,
                value: undefined,
            }
        }
        return {
            done: false,
            value: self[index++]
        }
    }
}
  • 对于类数组的对象,也想使用for of循环怎么实现?给obj加一个Symbol.iterator属性,让对象具备可迭代行,并且使用for of循环。
let obj={
    0: 100,
    1: 200,
    2: 300,
    length: 3,
}
obj[Symbol.iterator]=Array.prototype[Symbol.iterator];
for(const val of obj){
    console.log(val); // 100, 200, 300
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值