数组方式解构对象
经典真题
如何能让下面代码成立?
JavaScriptlet obj = { a : 1, b : 2 }; const [a,b] = obj; console.log(a,b)
题目解析
首先,你可以尝试去运行如上代码,会得到这样一个结果:
这里我不展开描述,只解释下面几个概念,你可以参阅 ECMAScipt 官方文档 关于解构。
- 什么叫
可迭代对象
?满足可迭代协议的对象。 - 什么叫
可迭代协议
?对象必须实现@@iterator
方法,该方法返回一个迭代器。 - 什么叫
迭代器
?对象必须实现next
方法,该方法返回一个对象,包含value
和done
属性。 - 什么叫
知名符号
?@@iterator
就是其中之一,这里我们要实现的是[Symbol.iterator]
。
接下来,我们来实现这样一个功能:
JavaScript
let obj = {
a: 1,
b: 2,
[Symbol.iterator]() {
let values = [this.a, this.b];
let index = 0;
return {
next() {
if (index < values.length) {
return {
value: values[index++],
done: false,
};
} else {
return {
value: undefined,
done: true,
};
}
},
};
},
};
当然,我们也可以通过生成器来实现这样的效果:
JavaScript
let obj = {
a: 1,
b: 2,
*[Symbol.iterator]() {
yield this.a;
yield this.b;
},
};
但是,如果要求你不可以修改 obj 的声明呢?
JavaScript
let obj = {
a: 1,
b: 2,
};
Object.prototype[Symbol.iterator] = function () {
const arr = [1,2];
return arr[Symbol.iterator]();
}
const [a, b] = obj;
console.log(a, b);
自然地,不建议你硬编码:
JavaScript
let obj = {
a: 1,
b: 2,
};
Object.prototype[Symbol.iterator] = function () {
const arr = Object.values(this);
return arr[Symbol.iterator]();
}
const [a, b] = obj;
console.log(a, b);
当然,你也可以一行代码搞定:
JavaScript
let obj = {
a: 1,
b: 2,
};
Object.prototype[Symbol.iterator] = function () {
return Object.values(this)[Symbol.iterator]();
}
const [a, b] = obj;
console.log(a, b);
进一步地,如果你的 ES6 学的足够透彻,你可以达到这样一个境界:
JavaScript
let obj = {
a: 1,
b: 2,
};
Object.prototype[Symbol.iterator] = function* () {
yield* Object.values(this);
};
const [a, b] = obj;
console.log(a, b);