为什么Object对象能被for...in遍历,for...of却不行。

133 阅读1分钟

为什么Object对象能被for...in遍历,for...of却不行。

for...in

for...in 语句以任意顺序迭代一个对象的除Symbol以外的可枚举属性,包括继承的可枚举属性。

const someObj = {
  d: 13,
  c: 23
};

for(let a in someObj) {
  console.log(a)
}
// d
// c

断章取义一下,for...in作用的目标是对象。

for...of

for...of语句在可迭代对象(包括 ArrayMapSetStringTypedArrayarguments对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句

const someObj = {
  d: 13,
  c: 23
};

for(let a of someObj) {
  console.log(a)
}

报错

for(let a of someObj) {
             ^

TypeError: someObj is not iterable
    at Object.<anonymous> (d:\vuespace\blog\test.js:6:14)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module._load (internal/modules/cjs/loader.js:790:12)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:75:12)
    at internal/main/run_main_module.js:17:47

for...of作用的目标是可迭代对象。而someObj不是一个可迭代对象。

所以呢,Object对象能被for...in遍历,for...of却不行。

加深理解

再看看下面的例子,加深理解。

const someObj = {
  test: '123',
  *[Symbol.iterator]() {
    yield "a";
    yield "b";
  },
};

for(let a of someObj) {
  console.log(a)
} 
// a
// b

for(let a in someObj) {
  console.log(a)
}
// test

console.log(...someObj) // a b

利用 Symbol.iteratorsomeObj 定义了默认的迭代器,所以这里不会报错。

这里 for...in 只迭代了 someObj 中的 test 属性。(至于为什么,看最上面的定义)

for...of作用到someObj的默认迭代器Symbol.iterator

扩展运算符也只作用到可迭代对象上。