const [a,b] = {a:1,b:2},为什么会出现这样的代码??

296 阅读2分钟

先上问题: 如何让以下代码成立呢

const obj = {a:1,b:2}
const [a,b] = obj
console.log(a,b) // 1, 2

for (let o of obj){
  console.log(o) // 1, 2
}

先来看看错误类型

当我们尝试通过解构赋值或者 for...of 循环遍历普通对象时,通常会收到类似以下错误的提示:对象不是可迭代的。 image.png

在JavaScript中,我们通常使用 for...of 循环来遍历可迭代对象。而数组是一种可迭代对象,因此我们可以直接使用 for...of 循环来遍历数组。数组的迭代器是通过内置的 Symbol.iterator 属性实现的,这使得我们无需手动定义迭代器就能对数组进行迭代。这就解释了为什么下面的代码可以正常运行:

const arr = [1,2,3]
for(let a of arr) {
    console.log(a)
}

然而,普通对象却不具备这种迭代特性,因此无法直接使用类似的方法进行遍历。那么,如何让普通对象也能够像数组一样进行迭代呢?

解决方案

为了让普通对象也能够实现迭代,我们需要手动为其定义一个迭代器。迭代器是一个对象,其包含一个 next() 方法,每次调用该方法都会返回一个包含 valuedone 属性的对象。通过手动定义一个迭代器,并将其绑定到对象的 Symbol.iterator 属性上,我们就可以使普通对象成为可迭代对象了。

直接上代码

const obj = {
  a: 1,
  b: 2,
  [Symbol.iterator]: function() {
    const keys = Object.keys(this);
    let index = 0;
    return {
      next: () => {
        if (index < keys.length) {
          const key = keys[index++];
          return { value: this[key], done: false };
        } else {
          return { done: true };
        }
      }
    };
  }
};

const [a, b] = obj;
console.log(a); // 输出 1
console.log(b); // 输出 2


for (let o of obj){
  console.log(o) // 1, 2
}

通过定义一个自定义的迭代器,我们可以让普通对象成为可迭代对象,从而可以使用解构赋值或者 for...of 循环来遍历对象。这种方式使得我们能够更加灵活地处理对象,并且能够提高代码的可读性和可维护性。