Web/05-JavaScript基础:ES6语法/05-ES6:变量的解构赋值.md
qianguyihao 4b3f7bade5 rename
2022-10-09 15:12:20 +08:00

216 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 05-ES6变量的解构赋值
---
<ArticleTopAd></ArticleTopAd>
## 解构赋值的概念
**解构赋值**ES6 允许我们,按照一一对应的方式,从数组或者对象中**提取值**,再将提取出来的值赋值给变量。
解构:分解数据结构;赋值:给变量赋值。
解构赋值在实际开发中可以大量减少我们的代码量,并且让程序结构更清晰。
## 数组的解构赋值
数组的结构赋值:将数组中的值按照**位置**提取出来,然后赋值给变量。
### 语法
在 ES6 之前,当我们在为一组变量赋值时,一般是这样写:
```javascript
var a = 1;
var b = 2;
var c = 3;
```
或者是这样写:
```js
var arr = [1, 2, 3];
var a = arr[0];
var b = arr[1];
var c = arr[2];
```
现在有了 ES6 之后,我们可以通过数组解构的方式进行赋值:(根据**位置**进行一一对应)
```javascript
let [a, b, c] = [1, 2, 3];
```
二者的效果是一样的,但明显后者的代码更简洁优雅。
### 未匹配到的情况
数据的结构赋值,是根据位置进行一一对应来赋值的。可如果左边的数量大于右边的数量时(也就是变量的数量大于值的数量时),多余的变量要怎么处理呢?
答案是:如果变量在一一对应时,没有找到对应的值,那么,**多余的变量会被赋值为 undefined**。
### 解构时,左边允许有默认值
在解构赋值时,是允许使用默认值的。举例如下:
```javascript
{
//一个变量时
let [foo = true] = [];
console.log(foo); //输出结果true
}
{
//两个变量时
let [a, b] = ['千古壹号']; //a 赋值为千古壹号。b没有赋值
console.log(a + ',' + b); //输出结果:千古壹号,undefined
}
{
//两个变量时
let [a, b = 'qianguyihao'] = ['千古壹号']; //a 赋值为千古壹号。b 采用默认值 qianguyihao
console.log(a + ',' + b); //输出结果:千古壹号,qianguyihao
}
```
### 将右边的 `undefined`和`null`赋值给变量
如果我们在赋值时,采用的是 `undefined`或者`null`,那会有什么区别呢?
```javascript
{
let [a, b = 'qianguyihao'] = ['千古壹号', undefined]; //b 虽然被赋值为 undefined但是 b 会采用默认值
console.log(a + ',' + b); //输出结果:千古壹号,qianguyihao
}
{
let [a, b = 'qianguyihao'] = ['千古壹号', null]; //b 被赋值为 null
console.log(a + ',' + b); //输出结果:千古壹号,null
}
```
上方代码分析:
- undefined相当于什么都没有此时 b 采用默认值。
- null相当于有值但值为 null。
## 对象的解构赋值
对象的结构赋值:将对象中的值按照**属性匹配的方式**提取出来,然后赋值给变量。
### 语法
在 ES6 之前,我们从接口拿到 json 数据后,一般这么赋值:
```javascript
var name = json.name;
var age = json.age;
var sex = json.sex;
```
上面这种写法,过于麻烦了。
现在,有了 ES6 之后,我们可以使用对象解构的方式进行赋值。举例如下:
```js
const person = { name: 'qianguyihao', age: 28, sex: '男' };
let { name, age, sex } = person; // 对象的结构赋值
console.log(name); // 打印结果qianguyihao
console.log(age); // 打印结果28
console.log(sex); // 打印结果:男
```
上方代码可以看出,对象的解构与数组的结构,有一个重要的区别:**数组**的元素是按次序排列的,变量的取值由它的**位置**决定;而**对象的属性没有次序**,是**根据键来取值**的。
### 未匹配到的情况
对象的结构赋值,是根据属性名进行一一对应来赋值的。可如果左边的数量大于右边的数量时(也就是变量的数量大于值的数量时),多余的变量要怎么处理呢?
答案是:如果变量在一一对应时,没有找到对应的值,那么,**多余的变量会被赋值为 undefined**。
### 给左边的变量自定义命名
对象的结构赋值里,左边的变量名一定要跟右边的属性名保持一致么?答案是不一定。我们可以单独给左边的变量自定义命名。
举例如下:
```js
const person = { name: 'qianguyihao', age: 28 };
let { name: myName, age: myAge } = person; // 对象的结构赋值
console.log(myName); // 打印结果qianguyihao
console.log(myAge); // 打印结果28
console.log(name); // 打印报错Uncaught ReferenceError: name is not defined
console.log(age); // 打印报错Uncaught ReferenceError: age is not defined
```
上方的第 2 行代码中:(请牢记)
- 等号左边的属性名 name、age 是对应等号右边的属性名。
- 等号左边的 myName、myAge 是左边自定义的变量名。
或者,我们也可以理解为:将右边 name 的值赋值给左边的 myName 变量,将右边 age 的值赋值给左边的 myAge 变量。现在,你应该一目了然了吧?
### 圆括号的使用
如果变量 foo 在解构之前就已经定义了,此时你再去解构,就会出现问题。下面是错误的代码,编译会报错:
```javascript
let foo = 'haha';
{ foo } = { foo: 'smyhvae' };
console.log(foo);
```
要解决报错,只要在解构的语句外边,加一个圆括号即可:
```javascript
let foo = 'haha';
({ foo } = { foo: 'smyhvae' });
console.log(foo); //输出结果smyhvae
```
## 字符串解构
字符串也可以解构,这是因为,此时字符串被转换成了一个类似数组的对象。举例如下:
```javascript
const [a, b, c, d] = 'hello';
console.log(a);
console.log(b);
console.log(c);
console.log(typeof a); //输出结果string
```
打印结果:
```
h
e
l
string
```
## 我的公众号
想学习**更多技能**?不妨关注我的微信公众号:**千古壹号**。
扫一扫,你将发现另一个全新的世界,而这将是一场美丽的意外:
![](https://img.smyhvae.com/20200102.png)