javascript中的循环迭代(for, while, do...while, for...in, for...of, 函数迭代)

457 阅读3分钟

循环

在大多数语言中,代码的大部分时间消耗在循环中。但是循环处理又是最常见的循环模式。也是提升性能必须要关注点。

循环类型

在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重要的事说三遍。