JavaScript的循环整理

81 阅读2分钟

for

特点:

  • 可控制循环起点,控制循环次数,但需要明确长度

while

特点:

  • 不知循环次数,由条件语句判断结束循环

forEach

特点:

  • 无法通过正常途径终止循环
  • 其回调函数会忽略空值
  • 循环起始位置无法控制

forEach详情

for of

特点:

  • iterator迭代器,具备next方法,每次执行返回一个对象【含value/done属性】
  • 可遍历数组,字符串,Set,Map等类数组
// 字符串
const str = '12345';
for (let val of str) {
    console.log(val); // 依次打印出12345
}
// Set
const _set = new Set([1,2,3,4,5]);
for (let val of _set) { // [key, val] // 会报Uncaught TypeError: .for is not iterable
    console.log(val); // 依次打印出12345
}
// Map
const _map = new Map();
_map.set('a', 1);
_map.set('b', 2);
_map.set('c', 3);
for (let [key, value] of _map) {
    console.log(key, value); // 依次打印出a 1,b 2, c 3
}
// arguments
function fn() {
    for (let val of arguments) { // [key, val] // 会报Uncaught TypeError: .for is not iterable
        console.log(val); // 依次打印出12345
    }
}
fn(1,2,3,4,5);
// NodeList
const nodeList = document.querySelectorAll('li');
for (let value of nodeList) {
    console.log(value); // <li.xxxx>...</li>
}
  • 不能遍历对象【对象没有实现迭代器规范】
const obj = { name: 'a', age: 12 };
for (let key of obj) {
    console.log(key); // Uncaught TypeError: obj is not iterable
}

for in

特点:

  • 会遍历到原型链上可枚举的属性
  • 遍历顺序以数字优先
  • 无法遍历Symbol属性
const obj = {
    name: 'abc',
    [Symbol('only')]: 2022,
    num: 1,
    boolean: true,
    str: 'string',
    1: 2023
};
for (let key in obj) {
    console.log(key); // 依次打印出 1, name, num, boolean, str
}

性能方面

const ary = new Array(9999999).fill(0);
// for
console.time('for');
for (let i = 0; i < ary.length; i++) {}
console.timeEnd('for');

// while
console.time('while');
let i = 0;
while(i < ary.length) { i++; }
console.timeEnd('while');

// forEach
console.time('forEach');
ary.forEach((item) => {});
console.timeEnd('forEach');

// for of
console.time('for of');
for (let val of ary) {}
console.timeEnd('for of');

// for in
console.time('for in');
for (let key in ary) {}
console.timeEnd('for in');

// for 多次运行,均在7~8ms
// while 多次运行,均在20~21ms
// forEach 多次运行,均在80~86ms
// for of 多次运行,均在100~120ms
// for in 多次运行,均在3000~3200ms

只以性能比较来说,for > while > forEach > for fo > for in

for in性能最差,与本身循环机制有关,因为for in会遍历当前对象中所有可枚举的属性,包括原型链上的‘’