5.变量的解构赋值 - JS

什么是解构赋值

  1. 通过类似(或相同)的构型,将已知数据的元素/属性解构并提取出来,再赋值到相应变量,可以是新建的变量,也可以是已存在的变量/属性等;
  2. 最常见的是数组和对象的解构赋值,基本语法如下。
/* 绑定模式:变量同用一个声明let/const */
/* 数组 */
const [a, b] = array;
let [a, , b] = array;
const [a = aDefault, b] = array;
let [a, b, ...rest] = array;
const [a, , b, ...rest] = array;
let [a, b, ...{ pop, push }] = array;
const [a, b, ...[c, d]] = array;
/* 对象 */
const { a, b } = obj;
let { a: a1, b: b1 } = obj;
const { a: a1 = aDefault, b = bDefault } = obj;
let { a, b, ...rest } = obj;
const { a: a1, b: b1, ...rest } = obj;
let { [key]: a } = obj;/* 赋值模式:变量的声明各自独立 */
let a, b, a1, b1, c, d, rest;
let pop, push;
[a, b] = array;
[a, , b] = array;
[a = aDefault, b] = array;
[a, b, ...rest] = array;
[a, , b, ...rest] = array;
[a, b, ...{ pop, push }] = array;
[a, b, ...[c, d]] = array;({ a, b } = obj); // 必须加上 ()
({ a: a1, b: b1 } = obj);
({ a: a1 = aDefault, b = bDefault } = obj);
({ a, b, ...rest } = obj);
({ a: a1, b: b1, ...rest } = obj);
  • 可以看到,声明和解构赋值在同一语句的是绑定模式;先声明再赋值的是赋值模式;
  • 下面根据不同数据类型,进行语法总结。

数组的解构赋值

将可迭代对象解构,赋值给数组模式里对应位置上的变量。

基本语法

  1. 完全的模式匹配,构型完全一致;
let [a, b] = [1, 2];
let [a, [b, c], [d], e] = [1, [2, 3], [4], 5];
  1. 数据更多,只赋值指定位置;
let [a, b] = [1, 2, 3]		// a=1,b=2
let [a, , b] = [1, 2, 3, 4]	// a=1,b=3,跳过第二个位置
  1. 数据更少,多余的变量赋值为 undefined
let [a, b, c] = [1, 2]			// c=undefined
let [a, [b, c], d] = [1, [2]]	// c=d=undefined
  1. 结合剩余参数,将剩余的数据作为数组赋值给最后一个变量;
let [a, ...rest] = [1, 2, 3, 4]				// rest = [2, 3, 4]
let [a, , ...rest] = [1, 2, 3, 4]			// rest = [3, 4]
let [a, [b, ...rest], c] = [1, [2, ], 3, 4]	// rest = []
  1. 带默认值的解构赋值;
let [a=1] = []			// a=1
let [a=1] = [undefined]	// a=1
let [a=1] = [null]		// a=null
  1. *将前面变量用作后面变量的默认值。
let [x, y=x, z=2*x] = [1]	// y=1,z=2
let [x, y=x] = [1, 10]		// y=10
let [x=y, y] = [1, 10]		// 这种写法易错、且没有太多意义,因为匹配是从左到右的

扩展部分

  1. 一个数据交换的便捷语法 [b, a] = [a, b]
  2. 一般的可迭代对象(MapSetString等)都可以通过数组模式进行解构赋值;
  3. *在函数参数列表中,起提取相应参数的作用,只有被提取的参数,后续会被传入函数。
let [a, b] = new Map([[1, 2],				// a=[1,2][3, 4],				// b=[3,4]
]);function* gen() {yield* [1, 2, 3]
}
let [x, y, z] = gen()	// x=1,y=2,z=3function firstPlusThird([first, ,third]) { return first + third; }
firstPlusThird([1, 2, 10, 20])	// 11

注意事项

  1. 可以嵌套;
  2. 剩余参数必须在最后一个位置;
  3. 只有在没有匹配成功的时候,才会执行默认值的表达式;
  4. 数组模式的右端的期待值是可迭代对象;
  5. 不要将可能匹配失败的变量,作为默认值。
let [a, ...rest, b] = [1, 2, 3, 4]	// 报错,剩余参数rest不能在中间
let [a=console.log(1)] = [1]		// a=1且不会执行console.log(1)
let [a=console.log(1)] = []			// a=undefined且执行console.log(1)
let [x=y,y] = []					// 报错,y没有匹配到就赋值给x,x、y都没有声明成功
let [x, y] = 1						// 报错
let [x] = null						// 报错

对象的解构赋值

解构对象的属性,给相同属性名的变量进行赋值;和数组模式不同的是属性没有次序,要根据属性名赋值。

基本语法

  1. 同名的属性(匹配成功->属性值赋值给对应变量) / 没有同名的属性(匹配失败->undefined);
const employee = {id: 42,isAdmin: true,salary: '1.8w',
};
let { id, isAdmin } = employee;	// id=42,isAdmin=true
let { isAdmin, id } = employee;	// id=42,isAdmin=true
let { wage } = employee;		// wage=undefined
  1. 将匹配到的属性赋值给其他名称的变量;
/*
*  : 后的才是变量名
*  : 前的是要匹配的属性名
*/
let { id:ID } = employee;		// ID=42,没有id这个变量
let { salary:wage } = employee; // wage='1.8w'
  1. 带有默认值;
const employee2 = {  }
let { id=1 } = employee;		// id=42,匹配成功了
let { id=1 } = employee2;		// id=1,匹配失败了
let { id:ID=1 } = employee;		// ID=42,匹配成功了
let { id:ID=1 } = employee2;	// ID=1,匹配失败了
  1. 嵌套;
const o = {done: false,materials: [ ['copper',], { obsidian: '3kg', granite: '10t' } ],rate: '0%',plus() { this.rate = 1 + +this.rate.slice(0, -1) + '%' }
}
let { materials: m } = o;		// m=[ ['copper',], { obsidian: '3kg', granite: '10t' } ]
let { materials: [a, b] } = o;	// a=['copper'],b={ obsidian: '3kg', granite: '10t' }
let { materials: [, { obsidian }] }	// obsidian='3kg'
  1. 带有计算属性。
let employee3 = { id: 12,isAdmin: true
};
let x = 'id'
let { [x]: theId } = employee3		// theId=12

扩展部分

  1. 数组/字符串等基本数据类型是特殊的对象,有自己的属性(length、0/1/…等索引),甚至原型链上的方法都可以赋值(尽管不能正常使用);
  2. 还有一些内置对象,MathDate 等一些好用的方法,可以独立使用的方法,都可以通过解构赋值的语法赋值给变量,使得调用更方便;
  3. *在函数参数列表中,起提取相应参数的作用,只有被提取的参数,后续会被传入函数;
  4. 当解构一个对象时,如果属性本身没有被访问,它将沿着原型链继续查找,如上面第1点。
let { 0:firstPos, 1:secondPos, length:len, at } = [1, 2, 3, 4]
firstPos	// 1
secondPos	// 2
len			// 4
at(0)		// 报错,因为没有指向的对象,脱离了数组let { max, sin, PI:pi } = Math
max(1, 4, 2)// 4
sin(pi/2)	// 1let user = { id: 32,name: 'Li Ming' }, user2 = {};
function getUserId({ id }) {return id;
}
getUserId(user)		// 32
getUserId(user2)	// undefined

注意事项

  1. 将属性赋值给其他名字的变量时,: 前的是属性名,不是建立的变量,也不会建立;
  2. {} 可以没有变量;
  3. nullundefined 不能解构的数据类型;
  4. 先声明再赋值的情况,需要用 () 包围。先声明后赋值模式的语句 + ()
let { x:y } = { x: 1 }		// 将属性x 的值赋值给y,创建了变量y,没有创建变量x
let { a: 1 } = null			// 报错
let {  } = null				// 报错
let { a: 1 } = undefined	// 报错
let {  } = undefined		// 报错
let m;
{ m } = { m: 'M' }			// 报错
({ m } = { m: 'M' })		// m=1
({} = { a: 1, b: 2 })		// 这样是允许的,尽管很怪

字符串的解构赋值

字符串既可以作为类数组,进行数组模式的解构赋值;也可以作为对象,进行对象的解构赋值。

let str = 'Hello';
let strArr;
/* 作为数组被解构 */
let [a, b, , ,c] = str;			// a='H',b='e',c='o'
/* 作为对象被解构 */
let { length:n, 0:firstChar }	// n=5,firstChar='H'
({ 0:strArr[0], [str.length-1]:strArr[1] } = str)
strArr	// ['H', 'o']

函数参数的解构赋值

上面数组和对象的解构赋值,扩展部分提到过。在参数列表中做解构的类型一般就是数组和对象模式:

  1. 数组模式,根据位置上匹配数据,提取出来并进行指定传参;
  2. 对象模式,根据属性名匹配到属性值,提取出来并进行指定传参;
  3. 匹配失败,传 undefined
let arr = [1, 2, 10, 20], obj = { value: 100 };
function getM([a, ,b], { value }) {return a + b > value ? a + b: value; // 取大
}getM(arr, obj)	// 100

应用

  1. 简单地,交换变量的值;
  2. 从函数返回多个值
  3. 函数的解构参数;
  4. 提取 JSON 数据;
  5. 等等等等。
function f() { return [1, 2, 3] }let [a, b, c] = f();	// a=1,b=2,c=3

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

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

相关文章

黑马程序员前端web入门:新浪新闻

黑马程序员前端web入门:新浪新闻 几点学习到的: 设置li无圆点: list-style: none;设置a无下划线:text-decoration: none;a属于行内元素,高度hegiht不起作用,可以设置 display: block; 把它变成块元素。此时&#xff0c…

万户 ezOFFICE wpsservlet SQL注入漏洞复现

0x01 产品简介 万户OA ezoffice是万户网络协同办公产品多年来一直将主要精力致力于中高端市场的一款OA协同办公软件产品,统一的基础管理平台,实现用户数据统一管理、权限统一分配、身份统一认证。统一规划门户网站群和协同办公平台,将外网信息维护、客户服务、互动交流和日…

数据安全与数据交易中的安全

数据安全与数据交易中的安全 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 数据交易是一个新的名词,之前只听过数据作为生产要素这个提法的时候,本来就觉得很新奇,24年初,1月21日&…

操作系统-调度算法-1(先来先服务算法 短作业优先 高响应比优先 )

文章目录 总览先来先服务算法例题 短作业优先例题(非抢占式的短作业优先调度算法)例题(抢占式的短作业优先调度算法)注意 FCFS和SJF两种算法的思考高响应比优先例题 小结 总览 先来先服务算法 不会导致饥饿:只要该进程…

Spring中用到的设计模式

简单工厂模式:BeanFactory 就是简单工厂模式的体现,根据类名创建对象,再根据传入的一个唯一标识来获得 Bean 对象。 工厂方法模式:FactoryBean就是典型的工厂方法模式。spring在使用getBean() 调用获得该 bean 时,会自动调用该 b…

拥抱变局,坚韧向新|复旦大学-华盛顿大学EMBA项目C20毕业典礼

12月初,复旦大学-华盛顿大学EMBA项目20班的学员们前往美国,完成了项目最后一次移动课堂,并在奥林商学院举办了毕业典礼。      20班的学员们在项目20周年之际入学,也是疫情以来第一个正式恢复线下授课的班级。虽然经历了一些波…

C语言基础13

今天是学习嵌入式相关内容的第十四天,以下是今日所学内容 1.结构体: 1.结构体类型定义 2.结构体变量的定义 3.结构体元素的访问 4.结构体的存储 内存对齐 结构体整体的大小必须为最大基本类型长度的整数倍 5.结构体作为函数参数 值传递 练习:定…

【pdf密码】怎么打印加密的PDF文件?

PDF文件是可以打开查看的,但是现在不能编辑、不能打印,功能栏中的功能都是灰色的,这种设置了加密的PDF文件该如何加密? 如果PDF中的大多数功能按钮以及打印按钮都是灰色的状态,那就证明是文件的问题导致不能打印的。 …

sqlmap的使用

2024.1.31 sqlmap支持五种不同的注入模式&#xff1a; 1、布尔盲注2、时间盲注3、报错注入4、联合注入5、堆叠注入 检测注入 GET请求的基本格式 ​python sqlmap.py -u <测试网址> Ps:不知道为什么我的sqlmap使用时前面要加python&#xff0c;而大部分其他教程没提到…

React、React Router、JSX 简单入门快速上手

React、React Router、JSX 简单入门快速上手 介绍特点 JSX使用js表达式渲染列表样式控制注意事项 入门脚手架创建react项目安装目录介绍入口文件解析 组件解析介绍函数式组件类组件 事件绑定注意点定义使用事件对象事件处理函数接收额外参数 组件状态状态的定义使用 组件通信父…

AcWing--子串分值-->贡献法,枚举

2868. 子串分值 - AcWing题库&#xff08;python) s[0] list(input()) #6 nlen(s) # 左边 l[0]*n # 右边 r[0]*n p[0]*26 # 枚举每个 for i in range (1,n): t ord(s[i])-ord("a") l[i]p[t] p[t]i for i in range (26): p[i]n for i in range (n-1,…

SqlServer日期格式转换

一、常用格式转换 Select CONVERT(varchar(100), GETDATE(), 8): 10:57:46 Select CONVERT(varchar(100), GETDATE(), 14): 10:57:46:967 Select CONVERT(varchar(100), GETDATE(), 20): 2020-05-16 10:57:47 Select CONVERT(varchar(100), GETDATE(), 21): 2020-05-16 10:57…

MySQL 索引 create index 详解

在MySQL中创建索引可以帮助提高查询性能&#xff0c;特别是对于涉及大量数据和复杂查询的表。以下是如何在MySQL中创建索引的基本语法&#xff1a; CREATE [UNIQUE|FULLTEXT] INDEX index_name ON table_name (column1, column2,...) [USING BTREE | HASH]; UNIQUE&#xff…

uniapp中mescroll的使用

1.视图 <mescroll-uniref"mescrollRef"init"mescrollInit"down"downCallback"up"upCallback":up"{auto:false,page:{num:0,size:10}}":fixed"false" </mescroll-uni> 2.js 1. 引入js文件&#xff0c…

Mac 终端可以使用yarn,但是vscode里面报错segmentation fault

Mac 终端可以使用yarn 但是vscode里面报错segmentation fault 查阅官网https://www.yarnpkg.cn/getting-started/install 在vscode运行corepack enable即可解决该问题

嵌入式-stm32-江科大-OLED调试工具

文章目录 一&#xff1a;OLED调试工具1.1 OLED显示屏介绍1.2 实验&#xff1a;在OLED显示屏的使用1.3 自己新增功能测试道友&#xff1a;今天没有开始的事&#xff0c;明天绝不会完成。 一&#xff1a;OLED调试工具 1.1 OLED显示屏介绍 学习任何一门语言就需要进行调试&#…

Spark SQL的高级用法

一. 快速生成多行的序列 需求:请生成一列数据, 内容为 1 , 2 , 3 , 4 ,5 -- 快速生成多行的序列 -- 方式一 select explode(split("1,2,3,4,5",",")); --方式二 /*序列函数sequence(start,stop,step):生成指定返回的列表数据[start,stop]必须传入,step步…

付费使用GitHub Copilot半年,我残了吗?

有些程序员担心使用AI编程助手来写程序,自己会残掉 代码都不写了,你还是程序员吗? 手生脚慢,你怕是只会写hello word了吧? 接下来我用自己的亲身经验,告诉你答案。 ---- 购买记录 ---- 2023年7月17号,我付费100美金购买了一年Copilot,下一次续费的日期是今年的7月1…

防火墙详解

一、基本定义 所谓“防火墙”是指一种将内部网和公众访问网&#xff08;如Internet&#xff09;分开的方法&#xff0c;它实际上是一种建立在现代通信网络技术和信息安全技术基础上的应用性安全技术&#xff0c;隔离技术。越来越多地应用于专用网络与公用网络的互联环境之中&a…

PYTHON蓝桥杯——每日一练(简单题)

题目 利用字母可以组成一些美丽的图形&#xff0c;下面给出了一个例子&#xff1a; ABCDEFG BABCDEF CBABCDE DCBABCD EDCBABC 这是一个5行7列的图形&#xff0c;请找出这个图形的规律&#xff0c;并输出一个n行m列的图形。 输入格式 输入一行&#xff0c;包含两个整数…