前端八股文: 数组解构赋值的本质-迭代协议

58 阅读2分钟

引言

在现代前端开发中,解构赋值以其简洁和直观的特点,为开发者提供了极大的便利。它允许我们从数组或对象中快速提取数据,并将其分配给新的变量。然而,许多开发者可能误以为数组解构赋值仅限于数组,这种认知限制了对这一特性的全面理解和应用。实际上,数组解构赋值的核心在于对象是否遵循了JavaScript中的"迭代协议"。
本文将探讨一个常见的前端面试题,揭示其背后的可迭代协议,并展示如何利用这一协议来解答面试题。

数组解构赋值使用

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

面试题: 如何实现对象的数组解构赋值

Q🙋:如何让 const [a, b] = {a: 1, b: 2} 成立?

运行这段代码会报错,因为对象不是可迭代的。这让我们思考,是否可以手动实现让对象可迭代,从而使用数组解构赋值操作?

// 未捕获的类型错误:{a: 1, b: 2}不是可迭代的
Uncaught TypeError: {(intermediate value)(intermediate value)} is not iterable

通过学习JavaScript中的“迭代协议”,我们了解到,在JavaScript中,可迭代协议指的是一个对象具有[Symbol.iterator]属性,这个属性返回一个迭代器。迭代器是一个对象,它有一个next方法,每次调用都会返回一个包含valuedone属性的对象。value属性表示当前的值,而done属性是一个布尔值,表示迭代是否完成。

Q: 对于上面的面试题,在不修改当前赋值代码的情况下,我们可以在这段代码之前做什么操作,让等式成立呢?

要使等式成立,需要让{a: 1, b: 2}对象成为可迭代的。现在我们不能修改这段代码给这个对象添加[Symbol.iterator],那么是否可以给Object.prototype原型上添加属性,这样通过原型链所有的Object就可以访问[Symbol.iterator]属性

Object.prototype[Symbol.iterator] = function (){
    return Object.values(this)[Symbol.iterator]();
}
const [a, b] = {a: 1, b: 2}
console.log(a, b); // 输出:1 2

感谢阅读,敬请斧正!