for...in 和 for...of有什么区别

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情

for...in 和 for...of有什么区别

1. 最明显的区别就是:

  • for...in 遍历得到 key
  • for...of 遍历得到 value

代码演示:

const arr = [10, 20,30]
for(let val in arr){
  console.log('for...in', val)
}
console.log('====我是分隔符====')
for(let val of arr){
  console.log('for...of', val)
}
复制代码

演示结果:

image.png

2. 二者适用于不同的数据类型

  • 遍历对象:for...in可以,for...of 不可以
  • 遍历Map Set: for..of 可以,for..in 不可以
  • 遍历 generator:for...of 可以,for...in 不可以

真的是这样吗?我们就来亲身测试一下!

顺便带着思考一下这个问题:什么时候用 for...of 什么时候用 for...in呢?

遍历对象时:

演示:

// 遍历对象
const obj = {
  name: '张三',
  city: 'beijing'
}
for(let val in obj){
  console.log('for...in', val)
}
for(let val of obj){
  console.log('for...of', val)
}
复制代码

演示结果:

image.png

我们可以看见for..in 正常进行了遍历。

但是 for...of 出现了报错,提示我们 obj 不是一个可以遍历的数据

遍历 set 时

演示:

// 遍历 Set 
const set = new Set([10, 20, 30])
for(let n in set) {
  console.log('for...in', n)
}
for(let n of set) {
  console.log('for...of', n)
}
复制代码

演示结果:

image.png

我们可以看见for..in 值是 undefined。

但是 for...of 正常进行了遍历。

遍历 map 时

演示:

// 遍历 Map 
const map = new Map([
  ['x', 10],
  ['x1', 110],
  ['x2', 210],
])
for(let m in map) {
  console.log('for...in', m)
}
for(let m of map) {
  console.log('for...of', m)
}
复制代码

演示结果:

image.png

我们可以看见for..in 值是 undefined。

但是 for...of 正常进行了遍历。

遍历 generator

代码演示:

// 遍历 generator
function* foo() {
  yield 10
  yield 20
  yield 30
}
for(let g in foo) {
  console.log('for...in', g)
}
for(let g of foo) {
  console.log('for...of', g)
}
复制代码

演示结果:

image.png

我们可以看见for..in 值是 undefined。

但是 for...of 正常进行了遍历。

二者在什么情况下可以使用呢?

到底那些数据可以用 for...in 那些可以用 for...of ?

在提出这个问题的时候,我们需要先知道:for...infor...of 可以用在哪?

for...in

可以用在可枚举的数据,如:

  • 对象
  • 数组
  • 字符串
什么是可枚举数据呢?

举个例子来说

const obj = { x: 100 }
复制代码

我们使用 Object.getOwnPropertyDescriptors 方法获取指定对象所有的自有属性的属性描述符。

image.png

这时候发现他的每一个属性中 enumerable 都是 true,这时候他就是可枚举的。

如果一个属性的enumerable为false,下面三个操作不会取到该属性。

for..in循环

Object.keys方法

JSON.stringify方法

所以一般情况下 对象、数组、字符串都是可枚举的

for...of

for...of用于可迭代的数据,如:

  • 数组
  • 字符串
  • Map
  • Set
什么是可迭代数据呢?

举个例子来说

const arr = [10, 20, 30]
复制代码

数组中有个 Symbol.iterator的属性:

  • 1.只要一个数据已经实现了Iterator接口, 那么这个数据就有一个叫做[Symbol.iterator]的属性
  • 2.[Symbol.iterator]的属性会返回一个函数
  • 3.[Symbol.iterator]返回的函数执行之后会返回一个对象
  • 4.[Symbol.iterator]函数返回的对象中又一个名称叫做next的方法
  • 5.next方法每次执行都会返回一个对象{value: 10, done: false}
  • 6.这个对象中存储了当前取出的数据和是否取完了的标记

image.png

就类似设计模式中的迭代器模式:

不断有next、next去调用:

  • A next() => B
  • B next() => C
  • 如此 如此

了解了上面的情况之后,我们也可以理解什么时候用 for...of 什么时候用 for...in?

  • for...in可以用在可枚举的数据
  • for...of用于可迭代的数据

猜你喜欢

转载自juejin.im/post/7104444342684614664