【03】ES6:解构赋值

一、数组的解构赋值

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

1、基本使用

遵循 “模式匹配” ,索引值相同的完成赋值

// 为变量赋值,只能直接指定值。
let a = 1
let b = 2
let c = 3// 解构赋值:从数组中提取值,按照对应位置,对变量赋值。
let [a, b, c] = [1, 2, 3]
let [foo, [[bar], baz]] = [1, [[2], 3]]
foo // 1
bar // 2
baz // 3let [ , , third] = ['foo', 'bar', 'baz']
third // 'baz'let [x, , y] = [1, 2, 3]
x // 1
y // 3let [head, ...tail] = [1, 2, 3, 4]
head // 1
tail // [2, 3, 4]let [x, y, ...z] = ['a']
x // 'a'
y // undefined
z // []

2、默认值

(1)默认值的基本用法

const [a, b] = []
console.log(a, b) // undefined undefinedconst [a = 1, b = 2] = []
console.log(a, b)    // 1 2

(2)默认值的生效条件

ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于 undefined,默认值才会生效。

const [a = 1, b = 2] = [3, 0] // 3 0
const [a = 1, b = 2] = [3, null] // 3 null
const [a = 1, b = 2] = [3] // 3 2const [x = 1] = [undefined] // 1
const [x = 1] = [null] // null

(3)默认值表达式

如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。

// x 能取到值,所以函数 f 根本不会执行
function f() {console.log('aaa')
}let [x = f()] = [1]

(4)默认值引用

默认值可以引用解构赋值的其他变量,但该变量必须已经声明。

let [x = 1, y = x] = [] // 1 1
let [x = 1, y = x] = [2] // 2 2
let [x = 1, y = x] = [1, 2] // 1 2
let [x = y, y = 1] = [] // ReferenceError: Cannot access 'y' before initialization (x 用 y 做默认值时,y 还没有声明)

3、数组解构赋值的应用

(1)类数组对象 arguments

function func() {const [a, b] = argumentsconsole.log(a, b)    // 1 2
}
func(1, 2)

(2)NodeList

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>NodeList</title>
</head>
<body>
<p>1</p>
<p>2</p>
<p>3</p>
<script>const [p1, p2, p3] = document.querySelectorAll('p')console.log(p1, p2, p3)/*<p>1</p><p>2</p><p>3</p>*/
</script>
</body>
</html>

(3)函数参数的解构赋值

const array = [1, 1]
// const add = arr => arr[0] + arr[1]
const add = ([x = 0, y = 0]) => x + y
console.log(add(array)) // 2
console.log(add([])) // 0
[[1, 2], [3, 4]].map(([a, b]) => a + b)
// [ 3, 7 ]

(4)交换变量的值

let x = 2, y = 1// 原来
let tmp = x
x = y
y = tmp// 现在
[x, y] = [y, x] // [x, y] = [1, 2]
console.log(x, y) // 1 2

(5)跳过某项值使用逗号隔开

在解构数组时,可以忽略不需要解构的值,可以使用逗号对解构的数组进行忽略操作,这样就不需要声明更多的变量去存值了:

var [a, , , b] = [10, 20, 30, 40]
console.log(a) // 10
console.log(b) // 40

(6)剩余参数中的使用

通常情况下,需要把剩余的数组项作为一个单独的数组,这个时候我们可以借助展开语法把剩下的数组中的值,作为一个单独的数组,如下:

var [a, b, ...rest] = [10, 20, 30, 40, 50]
console.log(a) // 10
console.log(b) // 20
console.log(rest) // [30, 40, 50]

在 rest 的后面不能有 逗号 不然会报错,程序会认出你后面还有值。…rest 是剩余参数的解构,所以只能放在数组的最后,在它之后不能再有变量,否则则会报错。

二、对象的解构赋值

1、基本使用

对象的解构和数组基本类似,对象解构的变量是在 {} 中定义的。

遵循 “模式匹配” ,属性名相同的完成赋值。

// 对象没有索引,但对象有更明确的键,通过键可以很方便地去对象中取值
let { foo, bar } = { foo: 'aaa', bar: 'bbb' }
foo // 'aaa'
bar // 'bbb'let { bar, foo, baz } = { foo: 'aaa', bar: 'bbb' }
foo // 'aaa'
bar // 'bbb'
baz // undefined

如果变量名与属性名不一致,必须写成下面这样。

// foo 是匹配的模式,baz 才是变量。真正被赋值的是变量 baz,而不是模式 foo。
let { foo: baz } = { foo: 'aaa', bar: 'bbb' }
baz // 'aaa'
foo // error: foo is not defined

2、默认值

默认值生效的条件是,对象的属性值严格等于 undefined。

如果默认值是表达式,默认值表达式是惰性求值的。

var { a = 10, b = 5 } = { a: 3 } // a = 3, b = 5
var { a = 10, b = 5 } = { a: 3, b: undefined } // a = 3, b = 5
var { a = 10, b = 5 } = { a: 3, b: null } // a = 3, b = null

3、对象解构赋值的应用

(1)对象作为函数参数

// 之前
const logPersonInfo = user => console.log(user.name, user.age)
logPersonInfo({ name: 'jerry', age: 18 }) // jerry 18// 之后
const logPersonInfo = ({ age = 21, name = 'tom' }) => console.log(name, age);
logPersonInfo({name: 'jerry', age: 18}) // jerry 18
logPersonInfo({}) // tom 21

(2)从函数返回多个值

// 返回一个数组
function example() {return [1, 2, 3]
}
let [a, b, c] = example()// 返回一个对象
function example() {return {foo: 1,bar: 2}
}
let { foo, bar } = example()

(3)复杂嵌套(多重解构赋值)

let obj = {p: ['Hello',{ y: 'World' }]
}// 这时 p 是模式,不是变量,因此不会被赋值。
let { p: [x, { y }] } = obj
x // 'Hello'
y // 'World'// p 作为变量赋值
let { p, p: [x, { y }] } = obj
x // 'Hello'
y // 'World'
p // ['Hello', {y: 'World'}]
const node = {loc: {start: {line: 1,column: 5}}
}
// 三次解构赋值,分别是对 loc、start、line 三个属性的解构赋值。
// 注意,最后一次对 line 属性的解构赋值之中,只有 line 是变量,loc 和 start 都是模式,不是变量.
let { loc, loc: { start }, loc: { start: { line }} } = node
line // 1
loc  // Object {start: Object}
start // Object {line: 1, column: 5}

(4)剩余参数中的使用

在对象的解构中也可以使用剩余参数,对象中没有解构的剩余属性做聚合操作,生成一个新的对象。

const { a, c, ...rest } = { a: 1, b: 2, c: 3, d: 4 }
console.log(a)     // 1
console.log(c)     // 3
console.log(rest)  // { b: 2, d: 4 }

4、注意点

(1)如果要将一个已经声明的变量用于解构赋值,必须非常小心。

// 错误的写法
let x
{ x } = { x: 1 }
// SyntaxError: syntax error

上面代码的写法会报错,因为 JavaScript 引擎会将 {x} 理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。

// 正确的写法
let x
({ x } = { x: 1 })

上面代码将整个解构赋值语句,放在一个圆括号里面,就可以正确执行。

(2)解构赋值允许等号左边的模式之中,不放置任何变量名。因此,可以写出非常古怪的赋值表达式。

({} = [true, false])
({} = 'abc')
({} = [])

上面的表达式虽然毫无意义,但是语法是合法的,可以执行。

(3)由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。

let arr = [1, 2, 3]
let { 0 : first, [arr.length - 1] : last } = arr
first // 1
last // 3

上面代码对数组进行对象解构。数组arr的0键对应的值是1,[arr.length - 1]就是2键,对应的值是3。

三、字符串的解构赋值

字符串也可以解构赋值。既可以用数组的形式来解构赋值,也可以用对象的形式来解构赋值。

// 数组形式解构赋值
const [a, b, , , c] = 'hello'
console.log(a, b, c) // h e o// 对象形式解构赋值
// 类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。
const { 0: a, 1: b, 4: o, length : len } = 'hello'
console.log(a, b, o, len) // h e o 5

四、数值和布尔值的解构赋值

只能按照对象的形式来解构赋值。(先自动将等号右边的值转为对象)

// 转化后的对象里没有任何的属性(没有 123 这个属性,也没有 true 这个属性)和方法,
// 所有的属性和方法都在它的继承 __proto__ 中,比如 toString 方法就是继承来的。
new Number(123)
new Boolean(true)// 里面的值只能是默认值,继承的方法倒是可以取到
const { a = 1, toString: s } = 123
console.log(a, s) // 1 [Function: toString]// 里面的值只能是默认值,继承的方法倒是可以取到
const { b = 1, toString } = true;
console.log(b, toString) // 1 [Function: toString]

五、undefined 和 null 没有解构赋值

解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于 undefined和 null 无法转为对象,所以对它们进行解构赋值,都会报错。

let { prop: x } = undefined // TypeError
let { prop: y } = null // TypeError

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

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

相关文章

Centos7 Python环境和yum修复

1、删除现有残余包 [rootlocalhost ]# rpm -qa|grep python|xargs rpm -ev --allmatches --nodeps[rootlocalhost ]# rpm -qa|grep yum|xargs rpm -ev --allmatches --nodeps[rootlocalhost ]# whereis python |xargs rm -frv[rootlocalhost ]# whereis python ##验证清除&…

mybatis注解方式动态标签时有特殊符号,出现元素内容必须由格式正确的字符数据或标记组成

原始代码demo Select("SELECT COUNT(1) FROM AAAA WHERE name #{nage} AND age< 4") public Integer sumXxxxx(String nage, String age);现需求改为nage可以为空&#xff0c;因此使用了动态拼接 Select("<script> SELECT COUNT(1) FROM AAAA WHERE …

SWT/Jface(2): 表格的编辑

前言 上节说到, 创建和渲染表格需要如下几个步骤: 接收源数据数组(也可以是单个对象或者其他集合类型): TableViewer.setInput(Object)渲染接收的数据 渲染表头: TableViewer.setLabelProvider(IBaseLabelProvider)渲染内容: TableViewer.setContentProvider(IContentProvide…

java.lang.IllegalArgumentException: java.net.UnknownHostException: xxx

windows系统下连接hdfs进行操作时&#xff0c;上来就出现java.lang.IllegalArgumentException: java.net.UnknownHostException: xxx java.lang.IllegalArgumentException: java.net.UnknownHostException: liujianat org.apache.hadoop.security.SecurityUtil.buildTokenServ…

Keil Vision5—新建工程project

注意&#xff1a;创建的工程目录必须是纯英文目录 目录 1.开始配置 2.为该路径下新建个文件夹 3.选择器件 4.工程配置 4.右击魔术棒&#xff0c;设置参数 ​编辑 &#xff08;1&#xff09;target配置 &#xff08;2&#xff09;output配置 &#xff08;3&#xff09;c…

字符串结尾空格比较相关参数BLANK_PAD_MODE(DM8:达梦数据库)

DM8:达梦数据库 字符串结尾空格比较相关参数BLANK_PAD_MODE 环境介绍1 BLANK_PAD_MODE01.1 初始化数据库1.2 创建测试表 T0 2 BLANK_PAD_MODE12.1 初始化数据库2.2 创建测试表 T1 3 BLANK_PAD_MODE只对字段varchar类型生效3.1 BLANK_PAD_MODE 对char 类型对比无效3.2 在两个数据…

计算机中了halo勒索病毒怎么清除,halo勒索病毒解密数据恢复

科技的进步加快了企业发展的步伐&#xff0c;网络技术的不断应用为企业的生产运营提供了极大帮助&#xff0c;但随之而来的网络安全威胁也不断增加&#xff0c;近期&#xff0c;云天数据恢复中心接到很多企业的求助&#xff0c;企业的计算机服务器遭到了halo勒索病毒攻击&#…

Jmeter快速入门

文章目录 1.安装Jmeter1.1.下载1.2.解压1.3.运行 2.快速入门2.1.设置中文语言2.2.基本用法 1.安装Jmeter Jmeter依赖于JDK&#xff0c;所以必须确保当前计算机上已经安装了JDK&#xff0c;并且配置了环境变量。 1.1.下载 可以Apache Jmeter官网下载&#xff0c;地址&#xf…

uni-app打包后,打开软件时使其横屏显示

找到page.json文件&#xff0c;在global加入以下代码&#xff1a; 这样就可以横屏显示了。

CANdelaStudio 使用教程 1

文章目录 CANdelaStudio 软件下载CANdelaStudio 软件的权限View Edition 和 Admin Edition 区别&#xff1a;打开文件 CDD / CDDT 文件新建 CDD 文件新建 CDDT 文件CDD 和 CDDT 文件的区别 CANdelaStudio 软件下载 1、 来到 Vector 官网下载中心 https://www.vector.com/cn/zh…

[shader] 光照入门(未完结。。。

反射 漫反射&#xff1a;而当物体表面粗糙时&#xff0c;我们把物体表面看作无数不同方向的微小镜面&#xff0c;则这些镜面反射出的光方向均不相同&#xff0c;这就是漫反射。 高光反射&#xff1a;我们假定物体表面光滑&#xff0c;只有一个镜面&#xff0c;那么所有的光都…

报错For debugging consider passing CUDA_LAUNCH_BLOCKING=1.

.报错For debugging consider passing CUDA_LAUNCH_BLOCKING1. /aten/src/ATen/native/cuda/NLLLoss2d.cu:103: nll_loss2d_forward_kernel: block: [29,0,0], thread: [707,0,0] Assertion t > 0 && t < n_classes failed. 报错信息如下&#xff1a; ./aten/…

力扣labuladong——一刷day46

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣971. 翻转二叉树以匹配先序遍历二、力扣987. 二叉树的垂序遍历三、力扣666. 路径总和 IV 前言 二叉树的递归分为「遍历」和「分解问题」两种思维模式&a…

面试:RocketMQ相关问题

文章目录 什么是 RocketMQ&#xff0c;有哪些使用场景&#xff1f;RocketMQ 由哪些⻆色组成&#xff0c;每个⻆色作用和特点是什么&#xff1f;RocketMQ 中的 Topic 和 JMS 的 queue 有什么区别&#xff1f;RocketMQ 消费模式有几种&#xff1f;RocketMQ 的 Consumer 是如何消费…

【深度学习】Python快捷调用InsightFace人脸检测,纯ONNX推理

pypi资料&#xff1a; https://pypi.org/project/insightface/ 模型选择&#xff1a; https://github.com/deepinsight/insightface/tree/master/python-package#model-zoo onnxruntime的GPU对应CUDA &#xff1a; https://onnxruntime.ai/docs/reference/compatibility …

1999-2021年地级市城镇居民人均消费性支出数据

1999-2021年地级市城镇居民人均消费性支出数据 1、时间&#xff1a;1999-2021年 2、指标&#xff1a;城镇居民人均消费性支出 3、范围&#xff1a;290个地级市 4、来源&#xff1a;城市年鉴、地级市统计公报 5、指标解释&#xff1a; 城镇居民人均消费性支出&#xff1a;指…

kubesphere安装依赖文件

yum install socat -y yum install conntrack -y

GAMES101-Homework2

目录 普通作业&#xff1a;提高作业&#xff1a;参考博客博客一博客二博客三 附代码框架的个人一些注释和理解&#xff1a;rasterizer.cppTriangle.cpp 普通作业&#xff1a; // 判断点是否在三角形内的辅助函数 static bool insideTriangle(float x, float y, const Vector3f…

再添千万级罚单,某银行年内罚款过亿!金融行业合规问题亟待解决

11月17日晚间&#xff0c;国家金融监管总局上海监管局披露行政处罚信息显示&#xff0c;某银行因32项违法违规事实收到两张690万元的大额罚单&#xff0c;合计罚款金额达1380万元。但这并不是银行该今年收到的第一张大额罚单。今年4月28日&#xff0c;该行因在结售汇、外币理财…

k8s-pod生命周期 4

容器环境初始化 pod 由pod 镜像来提供&#xff0c;在pod 生命周期里容器主要分为两种&#xff1a;初始化容器和主容器 初始化容器一定要成功运行并退出&#xff0c;当初始化容器运行退出完了之后主容器开始和运行 主容器开始运行的时候&#xff0c;有两个探针&#xff1a;存…