面试官:如何让 var [a, b] = {a: 1, b: 2} 解构赋值成功?

最近看到了一个面试题非常有意思,讲得是:如何让 var [a, b] = {a: 1, b: 2} 解构赋值成功?

最近看到了一个面试题非常有意思,讲得是:如何让 var [a, b] = {a: 1, b: 2} 解构赋值成功?

最近看到了一个面试题非常有意思,讲得是:如何让 var [a, b] = {a: 1, b: 2} 解构赋值成功?。

我们知道在 js 中[]代表数组,{}代表对象。但是在这个代码中:

  • 解构赋值语法的左侧是一个数组
  • 右侧则应该是一个具有迭代器接口的对象(如数组、Map、Set等)。

因此,将对象{a: 1, b: 2}解构赋值给[a, b]会导致语法错误,那么怎么解决呢?我们来看一下!

思路

错误思路

既然将一个对象解构赋值给数组,是一个语法错误,那我们直接把这个解构语法变为对象的解构赋值语法不就好了。直接改成var { a, b } = { a: 1, b: 2 };如果这样做的话,哈哈哈哈哈哈,恭喜你面试结束了。

所以我们得好好想清楚,这可是一个字节的面试题,它的考点可不是这么显而易见的。

正确解题思路

我们首先来看看报错是什么样的:

var [a, b] = {a: 1, b: 2}
TypeError: {(intermediate value)(intermediate value)} is not iterable

这个错误是个类型错误,并且是对象有问题,因为对象是一个不具备迭代器属性的数据结构。所以我们可以知道,这个面试题就是考验我们对于迭代器属性的认识,我们再来个场景加深下理解。

let arr = [1, 2, 3]
let obj = {
    a: 1,
    b: 2,
    c: 3
}
for(let item of arr){
    console.log(item)
}
for(let item of obj){
    console.log(item)
}

我们知道for of只能遍历具有迭代器属性的,在遍历数组的时候会打印出1 2 3,遍历对象时会报这样的一个错误TypeError: obj is not iterable,那么数组上的迭代器属性究竟是什么样的呢,我们来看一看。

面试官:如何让 var [a, b] = {a: 1, b: 2} 解构赋值成功?

我们可以在最下面发现,数组原型上有Symbol.iterator这样一个属性,这个属性显然是从Array身上继承到的,并且这个属性的值是一个函数体,如果我们调用一下这个函数体会怎么样?我们打印来看看

console.log(arr.__proto__[Symbol.iterator]());
// Object [Array Iterator] {}

最重要的点来了

它返回的是一个对象类型,并且是一个迭代器对象!!!所以一个可迭代对象的基本结构是这样的:

interable
{
    [Symbol.iterator]: function () {
        return 迭代器 (可通过next()就能读取到值)
    }
}

我们可以得出只要一个数据结构身上,具有[Symbol.iterator]这样一个属性,且值是一个函数体,可以返回一个迭代器的话,我们就称这个数据结构是可迭代的。

这时候我们回到面试题之中,面试官要我们让var [a, b] = {a: 1, b: 2}这个等式成立,那么有了上面的铺垫,我们可以知道,我们接下来的操作就是:人为的为对象打造一个迭代器出来,也就是让对象的隐式原型可以继承到迭代器属性,我们可以先这样做:

Object.prototype[Symbol.iterator] = function(){

}

var [a, b] = {a: 1, b: 2}
console.log(a,b);

这样的话,报错就改变了,变成:

TypeError: Result of the Symbol.iterator method is not an object

接下来,我们知道var [a, b] = [1, 2]这是肯定没有问题的,所以我们可以将对象身上的迭代器,打造成和数组身上的迭代器(arr[Symbol.iterator])一样,代码如下:

Object.prototype[Symbol.iterator] = function(){
    // 使用 Object.values(this) 方法获取对象的所有值,并返回这些值的迭代器对象
    return Object.values(this)[Symbol.iterator]()
}

这段代码是将Object.prototype上的[Symbol.iterator]方法重新定义为一个新的函数。新的函数通过调用Object.values(this)方法获取对象的所有值,并返回这些值的迭代器对象。

通过这个代码,我们可以使得任何 JavaScript 对象都具有了迭代能力。例如,对于一个对象obj,我们可以直接使用for...of循环或者...操作符来遍历它的所有值。

©本文为清一色官方代发,观点仅代表作者本人,与清一色无关。清一色对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文不作为投资理财建议,请读者仅作参考,并请自行承担全部责任。文中部分文字/图片/视频/音频等来源于网络,如侵犯到著作权人的权利,请与我们联系(微信/QQ:1074760229)。转载请注明出处:清一色财经

(0)
打赏 微信扫码打赏 微信扫码打赏 支付宝扫码打赏 支付宝扫码打赏
清一色的头像清一色管理团队
上一篇 2024年4月23日 17:06
下一篇 2024年4月23日 17:07

相关推荐

发表评论

登录后才能评论

联系我们

在线咨询:1643011589-QQbutton

手机:13798586780

QQ/微信:1074760229

QQ群:551893940

工作时间:工作日9:00-18:00,节假日休息

关注微信