字节面试官叫我把let [a, b, c] = { a: 1, b: 2, c: 3 }给成功解构掉,我慌的一批
前言
字节面试官问出这样一道面试题:let [a, b, c] = { a: 1, b: 2, c: 3 },请把它成功解构。 我:这不对啊,面试官,您是不是出错了,左边是对象吧?(好吧我承认不可能出这么简单的题),当我看见面试官摇着头的时候,我又慌了······
接下来,让我们从底层开始讲起,彻底搞明白这道面试题!
在JavaScript中,迭代器是一种对象,它提供了一个统一的方式来遍历数据集合,可以通过next()方法逐个访问集合中的元素。而for...of循环是ES6引入的一种语法结构,用于遍历可迭代对象(如数组、Map、Set等),它简化了对集合元素的遍历操作,不需要手动管理索引或调用迭代器的next方法,使得代码更加清晰和简洁。通过for...of循环,我们可以轻松地遍历数组、集合等数据结构,进行各种操作。
1. 为什么出现for of
我们引入这道题,其作用是对数组去重,我们可以发现这个时候是有点复杂的,因此js官方就打造了一种用来专门遍历具有迭代器属性的对象的for of。这便是for of的来源。其本意是把可以用不上复杂的普通for循环的事情交给它做。
2.迭代器(遍历器)
我们首先明确一点,for of只能遍历具有迭代器这个属性的对象。比如常见的数组。
我们观察这段代码,这就是一个迭代器内部所干的工作内容。我们通过传入实例对象,返回一个对象,这个对象内部有一个属性next,这个属性也是一个函数,这个函数返回结果。
我们首先要明确因为有闭包的存在导致外层函数即使被执行完毕,内层函数在外层函数外面使用时,仍然可以访问独立于内层函数而存在于外层函数之中的值。这段代码大致思路:我们定义一个i变量,如何返回一个对象,这个对象里有一个next属性是函数,这个函数首先判断i是不是大于这个传入参数的长度,如果不大于,done为false(代表没有遍历完毕),value就是i对应这个传参的值,否则是undefined。这里的话遍历器的底层我们就摸索完毕。
很明显,我们调用这个遍历器时,里面的next方法会返回每一次执行完毕的对象。只要done为false,就一定能够继续遍历。
这是一个大致的说明,也就是说,正是因为数组有迭代器这个属性,才可以用for of 进行数组的遍历。
我们看这段代码,按理来说对象是没有迭代器这个属性的,这里我们采用强加的方式(注意加入方式),这个时候对象就有了迭代器这个属性,并且我们调用这个属性对应函数时,返回的就是我们之前的那个迭代器。因此我们发现打印结果和这个对象没有半毛钱关系。这里也说明了一个事情,用for of 遍历的对象和这个对象内容没有直接联系,和这个对象的迭代器有关系(迭代器和这个对象内容有关系),相当于是有间接的关系。
这个时候打印出来的才是我们想要的结果。
3. for of 的底层原理
我们通过这段代码来了解for of 的底层原理,既然它遍历的是迭代器对象,而迭代器对象最终返回的是具有两个属性的对象,一个布尔值,一个具体遍历值。我们不能直接写出for of 这个方法,因此我们通过一个大致的方式来了解其底层原理。forof方法里接收遍历对象和回调函数,函数打印value值,这个时候我们首先定义迭代器,我们将这个对象的迭代器属性调用后,会返回一个对象。这个时候定义res,这个对象调用next方法会返回最终的对象,里面有value和done属性。所以我们只要当done属性为false的时候,就可以打印value,然后再次调用next方法,再次进入循环,直至done为true,至此遍历完毕!
数组解构的本质也是如此,我们可以发现,对数组进行解构的过程本质上也是获取这个数组的迭代器对象,然后调用迭代器对象的next方法然后获取value值顺位给解构中的每一个值。
这个便是具体的操作步骤。
4. 字节面试题
接下来,我们来一道最新字节面试题。
解构你会吧?那好,来吧,把对象里的属性解构到数组里去!
转载自:https://juejin.cn/post/7374308419074146313