js 中for ... in和 for ... of 区别

循环数组

for in 和 for of 都可以循环数组,for in 输出的是数组的index下标,而for of 输出的是数组的每一项的值。

const arr = [1,2,3,4]
 
// for ... in
for (const key in arr){
    
    
    console.log(key) // 输出 0,1,2,3
    }
 
// for ... of
for (const key of arr){
    
    
    console.log(key) // 输出 1,2,3,4
    }

循环对象

for in 可以遍历对象,for of 不能遍历对象,只能遍历带有iterator接口的,例如Set,Map,String,Array

const object = {
    
     name: 'lx', age: 23 }
    // for ... in
    for (const key in object) {
    
    
      console.log(key) // 输出 name,age
      console.log(object[key]) // 输出 lx,23
    }
 
    // for ... of
    for (const key of object) {
    
    
      console.log(key) // 报错 Uncaught TypeError: object is not iterable
    }

可以使用 for…in 循环遍历键名

for(let key in obj) {
    
    
   console.log('for in key', key)
 }
 /*
   for in key name
   for in key age
 */

也可以使用 Object.keys(obj) 方法将对象的键名生成一个数组,然后遍历这个数组

for(let key of Object.keys(obj)) {
    
    
   console.log('key', key)
 }
 /*
   key name
   key age
 */

for…in 循环不仅遍历数字键名,还会遍历手动添加的其它键,甚至包括原型链上的键。for…of 则不会这样

let arr = [1, 2, 3]
arr.set = 'world'  // 手动添加的键
Array.prototype.name = 'hello'  // 原型链上的键
 
for(let item in arr) {
    
    
  console.log('item', item)
}
 
/*
  item 0
  item 1
  item 2
  item set
  item name
*/
 
for(let value of arr) {
    
    
  console.log('value', value)
}
 
/*
  value 1
  value 2
  value 3
*/

forEach 循环无法中途跳出,break 命令或 return 命令都不能奏效

let arr = [1, 2, 3, 5, 9]
arr.forEach(item => {
    
    
  if(item % 2 === 0) {
    
    
    return
  }
  console.log('item', item)
})
/*
  item 1
  item 3
  item 5
  item 9
*/

for…of 循环可以与break、continue 和 return 配合使用,跳出循环

for(let item of arr) {
    
    
   if(item % 2 === 0) {
    
    
     break
   }
   console.log('item', item)
 }
 // item 1

无论是 for…in 还是 for…of 都不能遍历出 Symbol 类型的值,遍历 Symbol 类型的值需要用 Object.getOwnPropertySymbols() 方法

{
    
    
  let a = Symbol('a')
  let b = Symbol('b')

  let obj = {
    
    
    [a]: 'hello',
    [b]: 'world',
    c: 'es6',
    d: 'dom'
  }

  for(let key in obj) {
    
    
    console.info(key + ' --> ' + obj[key])
  }

  /*
    c --> es6
    d --> dom
  */

  let objSymbols = Object.getOwnPropertySymbols(obj)
  console.info(objSymbols)    //  [Symbol(a), Symbol(b)]
  objSymbols.forEach(item => {
    
    
    console.info(item.toString() + ' --> ' + obj[item])
  })

  /*
    Symbol(a) --> hello
    Symbol(b) --> world
  */

  // Reflect.ownKeys 方法可以返回所有类型的键名,包括常规键名和Symbol键名
  let keyArray = Reflect.ownKeys(obj)
  console.log(keyArray)      //  ["c", "d", Symbol(a), Symbol(b)]
}

循环数组对象

const list = [{
    
     name: 'lx' }, {
    
     age: 23 }]
    for (const val of list) {
    
    
      console.log(val) // 输出{ name: 'lx' }, { age: 23 }
      for (const key in val) {
    
    
        console.log(val[key]) // 输出 lx,23
      }
    }

总结

  • for in适合遍历对象,for of适合遍历数组。
  • for in遍历的是数组的索引,对象的属性,以及原型链上的属性。

猜你喜欢

转载自blog.csdn.net/u014212540/article/details/129416543
今日推荐