JS核心原理之迭代器

大厂面试真题:在不修改下面代码的情况下,如何使得该代码成立?

ts 复制代码
const [a,b] = {
    c:1,
    d:2
}
console.log(a,b) // 1 2

解构

首先来看看下面这行代码

js 复制代码
const [a,b] = [1,2]
console.log(a,b) // 1 2

const {c,d} = {
    c:3,
    d:4
}
console.log(c,d) // 3 4

显而易见,这行代码大家都能看懂,但如果换成下面这行代码呢?

js 复制代码
const {c,d} = {
    e:3,
    f:4
}
console.log(c,d) // undefined undefined

这种写法属于对象的解构赋值,其原理是:

在解构赋值时,JavaScript 会根据变量名(如 c、d)去右侧对象中查找同名属性,并将对应的属性值赋给变量。对象解构赋值本质上是通过属性名的匹配来完成的,而不是依赖于对象的迭代器或顺序。

所以这里可以解构,是因为对象字面量 {c:3, d:4} 拥有 c 和 d 两个属性,解构赋值语法会自动将它们提取出来赋值给同名变量。

迭代器

1. 什么是迭代器?

定义:在 JavaScript 中,迭代器是一个对象,它定义一个序列,并在终止时可能附带一个返回值。

更具体地说,迭代器是通过使用 next() 方法实现了迭代器协议的任何一个对象,该方法返回具有两个属性的对象:

js 复制代码
console.log(Array[Symbol.iterator]) // [GeneratorFunction (anonymous)]

console.log(Array[Symbol.iterator]()) // Object [Generator] {}

console.log(Array[Symbol.iterator]().next()) // {value: undefined, done: true}

所以这里就能理解:

js 复制代码
const [a,b] = [1,2] 
console.log(a,b) // 1 2

数组解构的本质是:

js 复制代码
const [a,b] = [1,2] 
// 相当于
const arr = [1,2]
const iterator = arr[Symbol.iterator]()
const a = iterator.next().value
const b = iterator.next().value
console.log(a,b) // 1 2

回归题目

如何使得其成立,相信大家应该心理已经有思路和答案了

ts 复制代码
const [a,b] = {
    c:1,
    d:2
}
console.log(a,b) // 1 2
  • 对象的原型上是没有[Symbol.iterator]这个方法的
js 复制代码
console.log(Array.prototype[Symbol.iterator]) // [Function: values]
console.log(Object.prototype[Symbol.iterator]) // undefined

这里只需要给Object的原型上实现这个迭代器方法就可以,具体如下⬇️

ts 复制代码
// 方法1: 手动迭代器实现
Object.prototype[Symbol.iterator] = function(){
    const keys = Object.keys(this) // Object.keys() 使用属性创建顺序(ES2015+规范)
    let index = 0
    return {
        next:()=>{
            if(index < keys.length){
                return {
                    value: this[keys[index++]],
                    done: false
                }
            }else{
                return {
                    value: undefined,
                    done: true
                }
            }
        }
    }
}

// 方法2:生成器函数实现(推荐)
Object.prototype[Symbol.iterator] = function*(){
    for(const key of Object.keys(this)){
        yield this[key];
    }
}

迭代器协议工作流程

JavaScript的设计哲学

"如果它像鸭子一样走路和叫,那它就是鸭子" - 鸭子类型

  • ​协议驱动​:只要对象实现了迭代接口,就能被当作可迭代对象
  • ​解构本质​:数组解构是迭代器语法糖,不要求原始数据结构
相关推荐
2501_9209317035 分钟前
React Native鸿蒙跨平台采用ScrollView的horizontal属性实现横向滚动实现特色游戏轮播和分类导航
javascript·react native·react.js·游戏·ecmascript·harmonyos
0思必得02 小时前
[Web自动化] Selenium处理动态网页
前端·爬虫·python·selenium·自动化
东东5163 小时前
智能社区管理系统的设计与实现ssm+vue
前端·javascript·vue.js·毕业设计·毕设
catino3 小时前
图片、文件的预览
前端·javascript
2501_920931704 小时前
React Native鸿蒙跨平台实现推箱子游戏,完成玩家移动与箱子推动,当所有箱子都被推到目标位置时,玩家获胜
javascript·react native·react.js·游戏·ecmascript·harmonyos
layman05285 小时前
webpack5 css-loader:从基础到原理
前端·css·webpack
半桔5 小时前
【前端小站】CSS 样式美学:从基础语法到界面精筑的实战宝典
前端·css·html
AI老李5 小时前
PostCSS完全指南:功能/配置/插件/SourceMap/AST/插件开发/自定义语法
前端·javascript·postcss
_OP_CHEN5 小时前
【前端开发之CSS】(一)初识 CSS:网页化妆术的终极指南,新手也能轻松拿捏页面美化!
前端·css·html·网页开发·样式表·界面美化
啊哈一半醒5 小时前
CSS 主流布局
前端·css·css布局·标准流 浮动 定位·flex grid 响应式布局