javascript中的循环迭代(for, while, do...while, for...in, for...of, 函数迭代)
循环
在大多数语言中,代码的大部分时间消耗在循环中。但是循环处理又是最常见的循环模式。也是提升性能必须要关注点。
循环类型
在js中中有四种经典的循环类型,while,do...while,for,for...in。以及es6新添加的for...of,和基于函数的迭代。
经典迭代
- for
for(let i = 0; i < 10; i++){
}
- while
var i = 10;
while(i > 0) {
i--;
}
- do...while
let i = 10;
do {
i--;
....
} while(i > 0)
- for...in
for(let prop of obj) {
}
四种循环,其中前三种的循环速度差不多,但是for...的速度比其他速度慢的多。因为每次迭代都会同时搜索实例和原形上的属性。如果可以的话不要使用for...in进行循环迭代。
es6迭代
- 基于函数迭代
如forEach,some, find,findIndex,map, reduce等都是基于函数迭代的,循环遍历数组的所有的成员,并在每个成员上执行函数。尽管此方法是一种便利的方法,但是每次迭代都会有函数调用,所以效率会比while,do...while的效率低。基于循环迭代比基于函数的迭代要快8倍左右(数字来自于:高性能javascript)
- for...of 迭代
for...of迭代现在主流的迭代方式,可以迭代数组,Set,Map,DOMList等,而且迭代语句很短。所以主要讲下for的使用方法
for...of迭代使用以及性能
性能
迭代速度对于经典迭代还是要慢,因为每次迭代都需要通过迭代器,迭代器的开销要比索引要大,这种区别在大型项目或对性能要求很高的项目中还是直管重要的,但是在平常开发中影响不会太大,远远不及带来的开发效率提示。
使用
- 数组
const arr = [1, 2];
for(const item of arr) {
console.log(item); // 1, 2
}
for...of 每次迭代返回数组中的每一项。且赋值给item,在循环体中可以直接使用item。
如果数组中的变量为对象,for...of循环可以直接解析赋值
const persons = [
{
name: '张三',
age: 20
},
{
name: '莉丝',
age: 20
}
];
for(const {name} of persons) {
console.log(name);
}
- Set 和Map迭代
es6中新增的Set和Map迭代都可以用for...of进行迭代。
const set = new Set([1, 2, 3, 3, 4]);
for(const item of set) {
console.log(item) // 1, 2, 3, 4
}
const map = new Map();
map.set('one', 1);
map.set('two', 2);
for(const [key, value] of map) {
console.log(key, value) // one 1, two, 2
}
- 类数组(DOM 集合/arguments)
- // dom集合迭代
- const children = document.body.children;
- for(let item of children){
- console.log(item) // child document
- }
- // arguments
- function sum(a, b) {
- for(item of arguments) {
- console.log(item)
- }
- }
sum(1, 2); // 1, 2
总体上来说es6提供的for...of和基于函数的迭代,都大大的减少的编写的代码量,同时让代码可维护性大大提高,如果不是对性能要求极高的项目可以使用for...of和基于函数迭代的方法。但是绝对不推荐使用 for...in, for...in, for...in重要的事说三遍。