当前位置: 首页 > news >正文

对象解构与迭代器的猫腻?

前言

变量的解构赋值是前端开发中经常用到的一个技巧,比如:

// 对象解构
const obj = { a: 1, b: 2 };
const { a, b } = obj;
console.log(a, b)数组解构
const arr = [1, 2, 3];
const [a, b] = arr;
console.log(a, b)

工作中我们最经常用的就是类似上面的对象和数组解构,好多同学就不禁问了,这个不是很简单吗。
那好,我们再来看一个:

// 不改动下面代码,如何使等式成立
const [a, b] = { a: 1, b: 2 };
console.log(a, b)

你觉得这个打印出来什么呢?
在这里插入图片描述

直接报错:{(intermediate value)(intermediate value)} is not iterable
翻译过来就是值是不可迭代的,这是为什么呢?因为右边的值是不可迭代对象

可迭代对象

什么是可迭代对象?
可迭代对象就是满足 可迭代协议 的对象。
可迭代协议 中必须有这么一个属性:Symbol.iterator,一个无参数的函数,其返回值为一个符合 可迭代协议 的对象,即迭代器。

数组解构

数组可以解构,因为数组是一个可迭代对象。

const arr = [1, 2, 3];
const iter = arr[Symbol.iterator]();
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())

我们看一下打印结果:
在这里插入图片描述

value代表的是这次迭代的值,done代表迭代是否完成。
这就是 可迭代协议 的规则。
数组解构就相当于下面这种写法:

const arr = [1, 2, 3];
// const [a,b] = arr;
const iter = arr[Symbol.iterator]();
const a = iter.next().value;
const b = iter.next().value;
console.log(a, b)

对象解构

那么问题来了,对象身上没有 Symbol.iterator,为什么还能解构?
因为对象的解构过程是这样的:创建对象 -> 枚举属性(OwnPropertyKeys) -> 复制属性,跟迭代器没关系。
对象解构就相当于下面这种写法:

const obj = { a: 1, b: 2 };
// const { a, b } = obj;
const a = obj.a;
const b = obj.b;

问题解决

我们捋清楚问题的起因,问题就好解决了,我们只需要在对象的原型上也添加一个 Symbol.iterator 属性就可以了:

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

这样就能使等式成立,而且如果你的 ES6 功底足够的扎实,还知道什么叫 生成器Generator,那你还可以这样写:

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

最终效果是一样的。

如果你对这些还不是很熟悉,建议你看一下 ES6 的文档:ECMAScript 6 入门教程

相关文章:

  • Go 使用 RabbitMQ---------------之一
  • Python零基础一天丝滑入门教程(非常详细)
  • layui扩展件(xm-select)实现下拉框
  • 【Python-基础】函数合集
  • EureKa是什么?
  • YOLOv10最详细全面讲解1- 目标检测-准备自己的数据集(YOLOv5,YOLOv8均适用)
  • clickhouse——ck目录介绍
  • 嵌入式要卷成下一个Java了吗?
  • Java高级面试问题及答案
  • 中科驭数驭云、超低时延网络案例双双入选第七届数字中国建设峰会数字化转型典型应用案例
  • C++ (week5):Linux系统编程3:线程
  • 数组-捡石子小游戏
  • 新零售数据中台:打造智能商业运营的核心引擎_光点科技
  • Owinps静态IP代理:跨境电商的优选解决方案
  • 【头歌】计算机网络DHCP服务器配置第二关access口配置答案
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • 2017届校招提前批面试回顾
  • 4. 路由到控制器 - Laravel从零开始教程
  • Apache Spark Streaming 使用实例
  • java2019面试题北京
  • JavaScript异步流程控制的前世今生
  • java中具有继承关系的类及其对象初始化顺序
  • jquery ajax学习笔记
  • LeetCode29.两数相除 JavaScript
  • SQLServer之创建数据库快照
  • 笨办法学C 练习34:动态数组
  • 从setTimeout-setInterval看JS线程
  • 看域名解析域名安全对SEO的影响
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 前端设计模式
  • 算法系列——算法入门之递归分而治之思想的实现
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 原生 js 实现移动端 Touch 滑动反弹
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • (3)选择元素——(17)练习(Exercises)
  • (5)STL算法之复制
  • (定时器/计数器)中断系统(详解与使用)
  • (二)JAVA使用POI操作excel
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (全注解开发)学习Spring-MVC的第三天
  • (十二)python网络爬虫(理论+实战)——实战:使用BeautfulSoup解析baidu热搜新闻数据
  • (转) Face-Resources
  • (转载)在C#用WM_COPYDATA消息来实现两个进程之间传递数据
  • .mysql secret在哪_MYSQL基本操作(上)
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .net core控制台应用程序初识
  • .Net Framework 4.x 程序到底运行在哪个 CLR 版本之上
  • .NET Standard 支持的 .NET Framework 和 .NET Core
  • .NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖
  • .NetCore项目nginx发布
  • @DataRedisTest测试redis从未如此丝滑
  • @Documented注解的作用
  • [ 数据结构 - C++] AVL树原理及实现