性能比较
for 循环和 while 循环的性能对比
let arr = new Array(999999).fill(1)
console.time('forTime')
for(let i = 0; i< arr.length; i++){}
console.timeEnd('forTime')
console.time('whileTime')
let i = 0
while(i< arr.length){
i ++
}
console.timeEnd('whileTime')
/* 输出
* forTime: 4.864990234375 ms
* whileTime: 8.35107421875 ms
*/
- 使用 let 声明下的循环,由于 for 中块级作用域的影响,内存得到释放,运行的运行的速度会更快一些。
- 使用 var 声明时因为for while 的循环都不存在块级作用域的影响,两者运行的速度基本一致。
forEach(callback, thisArg) 循环数组
callback 函数每一轮循环都会执行一次,且还可以接收三个参数(currentValue, index, array),index, array 也是可选
的,thisArg(可选) 是回调函数的 this 指向。
遍历可枚举的属性
let arr = new Array(999999).fill(1)
console.time('forEachTime')
arr.forEach(item =>{} )
console.timeEnd('forEachTime')
// forEachTime: 25.3291015625 ms
函数式编程的 forEach 性能消耗要更大一些。
for in 循环
for in 的循环性能循环很差。性能差的原因是因为:for in 会迭代对象原型链上一切 可以枚举的属性。
let arr = new Array(999999).fill(1)
console.time('forInTime')
for(let key in arr){}
console.timeEnd('forInTime')
// forInTime: 323.08984375 ms
for in 循环主要用于对象
let obj = {
name: '林一一',
age: 18,
0: 'number0',
1: 'number1',
[Symbol('a')]: 10
}
Object.prototype.fn = function(){}
for(let key in obj){
// if(!obj.hasOwnProperty(key)) break 阻止获取原型链上的公有属性 fn
console.log(key)
}
/* 输出
0
1
name
age
fn
*/
- (缺点) for in 循环主要遍历数字优先,由小到大遍历
- (缺点) for in 无法遍历 Symbol属性(不可枚举)。
- (缺点) for in 会将公有(prototype) 中可枚举的属性也遍历了。可以使用 hasOwnProperty来阻止遍历公有属性。
for of 循环
let arr = new Array(999999).fill(1)
console.time('forOfTime')
for(const value of arr){}
console.timeEnd('forOfTime')
// forOfTime: 33.513916015625 ms
for of 循环的原理是按照是否有迭代器规范来循环的,所有带有 Symbol.iterator 的都是实现了迭代器规范,比如数组一
部分类数组,Set,Map...,对象没有实现 Symbol.iterator 规范,所以不能使用for of循环。
- 使用 for of 循环,首先会先执行 Symbol.iterator 属性对应的函数且返回一个对象
- 对象内包含一个函数 next() 循环一次执行一次 next(),next() 中又返回一个对象
- 这个对象内包含两个值分别是 done:代表循环是否结束,true 代表结束;value:代表每次返回的值。
// Symbol.iterator 内部机制如下
let arr = [12, 23, 34]
arr[Symbol.iterator] = function () {
let self = this,
index = 0;
return {
next() {
if(index > self.length-1){
return {
done: true,
value: undefined
}
}
return {
done: false,
value: self[index++]
}
}
}
}