探索如何赋予对象迭代魔法,轻松实现非传统解构赋值的艺术

前言

今天下午在网上冲浪过程中看到这样一个问题
面试题:如何让 var [a, b] = {a: 1, b: 2} 解构赋值成功?
据说是某大厂面试题,于是我学习了一下这个问题,写下这篇文章记录一下。

学习过程

要想解决这个问题首先要知道什么是解构赋值。
解构赋值是ES6中一种将数组或对象的属性/元素值赋给变量的语法。

运行一下题目的代码得到下面的情况
在这里插入图片描述

原因是对象的解构赋值需要使用对应的属性名来匹配,而不是数组的形式。
比如var {a, b} = {a: 1, b: 2} 就可以成功实现结构赋值。
但是这么高贵的问题,你10秒就回答完了,回去等通知吧。

两个普通想法

  1. 将对象属性解构到数组变量中
    首先使用Object.keys获取对象的所有键,然后使用map方法根据这些键从对象中提取对应的值,最后将这些值解构到一个数组变量中。
        var arr = [a, b];var obj = { a: 1, b: 2 }// 获取对象的键数组var keys = Object.keys(obj)// 根据键获取对应的值var values = keys.map(key => obj[key])//数组解构赋值var [a, b] = values;console.log([a, b])

在这里插入图片描述

  1. 将数组元素解构到对象变量中
    创建了一个空对象obj,然后使用数组解构赋值直接将数组的元素赋值给对象的属性。
        var arr = [1, 2];var obj = {};[obj.a, obj.b] = arr; // 数组解构赋值到对象属性console.log(obj); // 输出: {a: 1, b: 2}

在这里插入图片描述

高级解法

在JavaScript中数据是具有迭代器属性的一种数据结构,而对象是不具有迭代器的一种数据结构。
最直白淳朴的想法,解构赋值成功只需要把右边也变成可以迭代的对象就可以了。
在 JavaScript 中,可迭代对象是指具有 Symbol.iterator 方法的对象。这个方法返回一个迭代器(Iterator)对象,它通过 next() 方法提供对可迭代对象中的每个元素的访问。
JavaScript中数组,Set,Map,字符串都是可以迭代的对象,任何有iterator接口的对象都是可迭代的,我们可以自定义一个有iterator接口的对象。
网友做法

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

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

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

给Object对象原型添加迭代器属性之后成功实现var [a, b] = { a: 1, b: 2 }解构赋值
在这里插入图片描述

题目拓展

上面通过给Object对象原型添加迭代器属性返回对象的值实现var [a, b] = { a: 1, b: 2 }解构赋值,但是若题目改为var [a, b] = { b: 1, z: 4 },会出现key不对应导致的问题。
运行下面的代码

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

运行结果如图
在这里插入图片描述

输出结果a应该是undefined,b:1,但是实际结果仍旧是a:1,b:4。
只是将{ b: 1, z: 4 }转成数组之后直接赋值,但是没有考虑到key的对应关系

最终优化结果

生成器函数function* () {}定义了一个迭代器生成器。当该迭代器被调用时,它会返回一个可迭代对象,并且通过yield*语句将对象的值作为迭代器的值逐个产生出来。为了在解构赋值时考虑到对象键的对应关系,我们需要修改迭代器函数,使其按照对象的键顺序来生成值。我们可以使用Object.entries方法来获取对象的键值对数组,然后按照这个顺序来生成值。

        Object.prototype[Symbol.iterator] = function* () {let entries = Object.entries(this); // 获取对象的键值对数组let arr = ['a', 'b']; // 假设这是我们关心的键的数组for (let entry of entries) {let key = entry[0]; // 获取键if (arr.includes(key)) { // 检查键是否在数组中yield entry[1]; // 如果键在数组中,则生成对应的值}}};// 使用数组解构赋值var [a, b] = { a: 1, z: 2, c: 3 }; // 这里我们只关心键 'a'console.log([a, b]);

在这里插入图片描述

首先给Object.prototype添加了一个自定义的迭代器,它使用Object.entries来获取对象的键值对数组,并按照这个数组的顺序来生成值。然后使用数组解构赋值来尝试解构一个对象,但是由于对象的键顺序是’b’, ‘z’,而我们只关心值’1’,所以变量a被赋值为’1’,而变量b因为没有对应的值而被赋值为undefined。


总结一下代码的步骤就是

  1. 添加迭代器: 通过给Object.prototype添加一个名为Symbol.iterator的方法,所有的对象都可以被迭代。
  2. 定义关心的键: 在迭代器内部定义一个数组arr其中包含迭代过程中关心的键名。
  3. 迭代对象属性: 使用Object.entries(this)获取对象的键值对数组,这里的this指的是调用迭代器的对象。
  4. 过滤属性: 在遍历键值对数组时,我们检查每个键是否在我们关心的键数组arr中。如果键存在,我们才生成对应的值。
  5. 解构赋值: 使用数组解构赋值来提取我们关心的键对应的值。由于迭代器已经过滤掉了不需要的属性,解构赋值只会得到我们想要的值。

额外的小问题:为什么上面的代码中是 let arr = [‘a’, ‘b’];不是let arr = [a, b]?

let arr = [a, b]是错误的,在声明arr数组的时候,变量a,b没有定义,没有具体的值不能用来初始化数组。
错误的运行结果是a is not defined

总结

本文解决如何让 var [a, b] = {a: 1, b: 2} 解构赋值成功的问题的最佳实践大概是通过扩展Object.prototype来为所有对象添加一个自定义的迭代器,该迭代器允许我们以一种特定的方式遍历对象的属性。具体来说,这个迭代器会过滤掉我们不关心的属性,只返回我们指定键名对应的属性值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/368890.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt:7.QWidget属性介绍(cursor属性-光标形状、font属性-控件文本样式、tooltip属性-控件提示信息)

目录 一、cursor属性-光标形状: 1.1cursor属性介绍: 1.2获取当前光标形状——cursor(): 1.3 设置光标的形状——setCursor(): 1.4 设置自定义图片为光标: 二、font属性-控件文本样式: 2.1font属性介绍…

excel PivotTable 透视表

开发数据导出excel功能,设置导出透视表 数据源: 透视表: 使用插件EPPlus 数据源: IF OBJECT_ID(tempdb..#temptable) IS NOT NULLDROP TABLE #temptable; CREATE TABLE #temptable ( [PROJECT] varchar(50), [PRODUCT_CODE] var…

VSCode 自动调整格式失效了 ESLint

ESLint【最新注意2.4.4版本有问题,需退回2.4.2版本就恢复正常了】 参考:vscode自动格式化失效_vscode保存自动格式化失效-CSDN博客

AI PC(智能电脑)技术分析

一文看懂AI PC(智能电脑) 2024年,英特尔、英伟达等芯片巨头革新CPU技术,融入AI算力,为传统PC带来质的飞跃,引领智能计算新时代。 2024年,因此被叫作人工智能电脑(AI PC)…

一文带你初探FreeRTOS信号量

本文记录我初步学习FreeRTOS的信号量的知识,在此记录分享,希望我的分享对你有所帮助! 什么是信号量 在FreeRTOS中,信号量(Semaphore)是一种用于任务间同步和资源共享的机制。信号量主要用于管理对共享资源的…

汽车电子行业知识:什么是电子后视镜

文章目录 1.什么是电子后视镜2.有哪些汽车用到了电子后视镜3.电子后视镜的原理及算法4.电子后视镜的优点5.电子后视镜的未来市场将继续增长 1.什么是电子后视镜 电子后视镜是一种集成了电子元件和显示屏的汽车后视镜,用于替代传统的机械后视镜。它通过内置的摄像头捕…

九浅一深Jemalloc5.3.0 -- ⑨浅*gc

目前市面上有不少分析Jemalloc老版本的博文,但5.3.0却少之又少。而且5.3.0的架构与之前的版本也有较大不同,本着“与时俱进”、“由浅入深”的宗旨,我将逐步分析Jemalloc5.3.0的实现。 另外,单讲实现代码是极其枯燥的,…

使用React复刻ThreeJS官网示例——keyframes动画

最近在看three.js相关的东西,想着学习一下threejs给的examples。源码是用html结合js写的,恰好最近也在学习react,就用react框架学习一下。 本文参考的是threeJs给的第一个示例 three.js examples (threejs.org) 一、下载threeJS源码 通常我们…

go开源webssh终端源码main.go分析

1.地址: https://github.com/Jrohy/webssh.git 2.添加中文注释地址: https://github.com/tonyimax/webssh_cn.git main.go分析 主包名:main package main //主包名 依赖包加载 //导入依赖包 import ("embed" //可执行文件…

申请SSL证书 SSL是如何保护网站安全的

随着互联网的不断发展,网络安全问题日益凸显,特别是在数据传输和存储方面。为了保护网站和用户的数据安全,SSL(安全套接层)技术应运而生,成为了保护网站安全的重要工具。本文将详细介绍SSL如何保护网站安全…

星光云720全景VR系统源码

星光云720全景VR系统源码 系统体验地址项目介绍JDK版本后端主要依赖前端框架前端node 版本用户端框架介绍技术选型依赖全景内容简介系统图片部分功能截图系统体验地址 系统体验地址 VR全景系统体验地址 账号:18175760278 密码:12345678 项目介绍 JDK版…

C语言_指针初阶(进阶还在更新中)

指针是什么 指针是内存中一个最小单元的编号,也就是地址平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量指针就是地址,口语中说的指针通常指的是指针变量。我们可以通过&(取地址操作符&#xff…

WSL——忘记root密码(Ubuntu)

1、问题描述 Windows下的WSL(Ubuntu)忘记了root密码,无法使用管理员权限。 2、解决方法 关闭 Ubuntu 窗口。打开 Windows 的 Powershell 或 cmd, 以 root 默认登陆 WSL。 wsl -u root 修改对应用户密码。 # xxx为要修改密码的用…

2024年第十四届APMCM亚太地区大学生数学建模竞赛

C 题 基于量子计算的物流配送问题 随着电子商务的迅猛发展,电商平台对物流配送的需求日益增长。为了确保货物能够按时、高效地送达消费者手中,电商平台与第三方物流公司建立了紧密的合作关系。然而,面对大量的货物和多样的目的地&#xff0c…

女性经济崛起,天润融通用客户感知挖掘市场潜力

每逢一年一度的国际妇女节,“女性”话题都会被郑重地讨论。 从消费市场上来说,最近几年女性群体正在拥有越来越大的影响力,甚至出现了“她经济”这样的专属词汇在最近几年被市场反复讨论。 毫无疑问,女性消费群体的崛起已经成为…

EXTI寄存器,AFIO的简洁,EXTI配置的流程

一,AFIO简介 AFIO是Alternate Function Input/Output 的缩写,表示复用功能IO,主要用于实现IO端口的复用功能以及外部中断的控制 STM32外设有很多I/O以及内置外设(如12C,ADC,ISP,USART等)。为节省引出管脚的…

科普文:Linux服务器性能调优概叙

概叙 Java web应用性能分析之服务端慢和优化概叙_cpu飙高java-CSDN博客 Java web应用性能分析之【CPU飙升分析概述】_web页面性能分析cpu占满是因为死循环,还是循环过多-CSDN博客 在我们的软件服务中,软件部署的服务器,一般都是linux服务器&#xff0c…

Hadoop-11-MapReduce JOIN 操作的Java实现 Driver Mapper Reducer具体实现逻辑 模拟SQL进行联表操作

章节内容 上一节我们完成了: MapReduce的介绍Hadoop序列化介绍Mapper编写规范Reducer编写规范Driver编写规范WordCount功能开发WordCount本地测试 背景介绍 这里是三台公网云服务器,每台 2C4G,搭建一个Hadoop的学习环境,供我学…

实验六 SQL数据查询—单表查询

题目 打开ecommerce数据库,用SQL语句完成下列各项查询要求: 查询每位员工的员工编号empno、员工姓名empname、联系电话telephone和所在部门名称depname查询已下订单的商品的orderno、memname、proname、qty、totalmoney信息查询会员订单总金额超过2000的…