js for,for...in,for...fo, forEach

446 阅读2分钟

var arr = [0,1,2,3,4]

  • for:

for(var i=0;i<arr.length;i++) {   console.log(arr[i]) // 获取下标}

  • forEach优点:简单,可以同时访问数组的下标与元素值,缺:不能中断循环

 arr.forEach(function(val,index){     
      console.log(val+'下标:',arr[index])   
       // 0下标: 0  1下标: 1,2下标: 2, 3下标: 3, 4下标: 4 
 })

  •  for-in循环:为循环‘enumerable’对象而设置的

var obj = {a:1, b:2, c:3}; 
for(var i in obj) {
   console.log(i + ':'+ obj[i]) // a:1, b:2, c:3    
}

也可以循环一个数组:但是不推荐,for in主要是循环带有key的对象方法

 for(var i in arr) {   // 可以返回下标和值        
     console.log(i + ':'+ arr[i])  // 0:0 1:1 2:2 3:3 4:4
 }

  • for-of循环:可以遍历字符串,Maps(映射),Sets(集合) ....
  1. 遍历字符串

let string = 'string';
for(let index of string) {
   console.log(index); // "s" "t" "r" "i" "n" "g"
}      

   2. 遍历数组:for... of使用entries()可以返回数组的下标

const iterable = ['苹果','土豆','番茄']
for(let [val,index] of iterable.entries()) { //返回对应的值和对应的下标
   console.log(val,index);
}

   3. Maps对象就是存储key-value(健值)对

const remap = new Map([['one',1],['two',2]]);
for(const [key,val] of remap) {
    console.log(key + '值:', val); // one值:1;two值:2
}

   4. Set(集合)允许存储任意类型的唯一值

const iter = new Set([1,2,3,4,1])
for (const val of iter) {    
    console.log(val);  // 1,2,3,4
}

  5. 遍历DOM collectiion

let Ul = document.querySelectorAll('ul');
for (let i of UL) {
    i.classList.add('red');
}

  • for...in和for..of对比
       for in :不光可以打印出枚举出的数组,还可以从构造函数的原型中查找继承的非枚举属性,for..of不行。

 Array.prototype.newArr = () =>{}; 
 Array.prototype.anotherNewArr = () => {}; 
 const array = ['foo','bar','baz']; 
 for (const val in array) {
    console.log(val);   // foo bar baz newArr anotherNewArr 
 }

数组的空元素:

const outerarr = ['a',,'b']outerarr.length // 3

for, for...in, for...of,forEach遍历['a', ,'b']和['a', undefined, 'b']

// for 打印"a, undefined, b" 
for (let i = 0; i < outerarr.length; ++i) {
   console.log(outerarr[i]);  
}

// for...of 打印"a, undefined, c"  
for (const i of outerarr) {
    console.log(i);  
}

// for...in 打印"a,b"   
for(let i in outerarr) {
   console.log(i)   
} 

// forEach打印"a,b"    
outerarr.forEach((val,index) =>{
    console.log(val)    
})

总结:for...in和forEach打印不会把undefined打印出来,数组中的空元素被称为"holes"。如果你想避免这个问题,可以考虑禁用forEach:

parserOptions:
    ecmaVersion: 2018
rules:
    no-restricted-syntax:
        - error
        - selector: CallExpression[callee.property.name="forEach"]
          message: Do not use `forEach()`, use `for/of` instead

总结:

简单地说,for/of是遍历数组最可靠的方式,它比for循环简洁,并且没有for/inforEach()那么多奇怪的特例。for/of的缺点是我们取索引值不方便,而且不能这样链式调用forEach(). forEach()


参考:juejin.cn/post/684490…