JS中三类循环对比以及性能分析

for 与 while

  • 基础 var 循环的时候,两者性能差不多
let arr = new Array(9999999).fill(0);

console.time('for')
for(var i = 0; i < arr.length; i++) {}
console.timeEnd('for')  // for: 8.13818359375 ms

console.time('while')
var i = 0;
while(i < arr.length) {
  i++;
}
console.timeEnd('while') // while: 8.020751953125 ms

var 没有块级作用域概念,创建的变量是全局的。全局状态下 i 会占用一定的内存空间,不被释放的情况下,会一直占用空间

  • 基于 let 循环的时候,for 循环性能更好
let arr = new Array(9999999).fill(0);

console.time('for')
for(let i = 0; i < arr.length; i++) {}
console.timeEnd('for')  // for: 4.476806640625 ms

console.time('while')
let i = 0;
while(i < arr.length) {
  i++;
}
console.timeEnd('while') // while: 10.82080078125 ms

let 是块级作用域,i 属于当前循环中的变量。此次循环结束的时候,i 就被释放,不会占用空间

for 循环没有创造全局不释放的变量

while 循环只能放条件,此时 let 依然在全局作用域下。占用的空间未被释放,所以 while 比 for 性能慢一些

forEach

  • forEach 的性能,远远低于 for 与 while
let arr = new Array(9999999).fill(0);

console.time('forEach')
arr.forEach(function(item){})
console.timeEnd('forEach')	//forEach: 63.18896484375 ms

forEach 会将结果帮我们封装起来,用起来很方便。然而 forEach 无法管控过程,性能上也有所消耗

  • 手写forEach
let a = [1,2,3]
let arr = new Array(a);

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

console.time('forEach')
arr.forEach(function(item){
  console.log(item);          /// [1,2,3]
})
console.timeEnd('forEach')

for in

  • 性能很差:迭代当前对象中所有可枚举的属性,查找机制会搞到原型链上
let arr = new Array(9999999).fill(0);

console.time('in')
for(let key in arr){}
console.timeEnd('in')   // in: 1654.09619140625 ms
  • 问题一:遍历顺序以数字优先
  • 问题二:无法遍历 Symbol 属性
  • 问题三:可以遍历到公有中可枚举的
Object.prototype.fn = function fn() {};
let obj = {
  name: 'aa',
  age: 18,
  [Symbol('AA')]: 100,
  1: 100,
  2: 200
}
console.time('in')
for(let key in obj){
  // console.log(obj.hasOwnProperty(key)); 
  // hasOwnProperty()方法会返回一个布尔值,判断对象是否自身属性
    
  // if(!obj.hasOwnProperty(key)) break;  可解决第三个问题,fn不会被遍历出来
  console.log(key);     // 1 2 name age fn
}
console.timeEnd('in')  

for of

  • of 循环的原理是按照迭代器规范遍历的(对象默认不具备迭代器规范)
  • 比 in 性能快很多,远远低于 for while
let arr = new Array(9999999).fill(0);

console.time('of')
for(let val of arr){}
console.timeEnd('of') // of: 86.7080078125 ms
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值