CodeAshen's blog CodeAshen's blog
首页
  • Spring Framework

    • 《剖析Spring5核心原理》
    • 《Spring源码轻松学》
  • Spring Boot

    • Spring Boot 2.0深度实践
  • Spring Cloud

    • Spring Cloud
    • Spring Cloud Alibaba
  • RabbitMQ
  • RocketMQ
  • Kafka
  • MySQL8.0详解
  • Redis从入门到高可用
  • Elastic Stack
  • 操作系统
  • 计算机网络
  • 数据结构与算法
  • 云原生
  • Devops
  • 前端
  • 实用工具
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
  • Reference
GitHub (opens new window)

CodeAshen

后端界的小学生
首页
  • Spring Framework

    • 《剖析Spring5核心原理》
    • 《Spring源码轻松学》
  • Spring Boot

    • Spring Boot 2.0深度实践
  • Spring Cloud

    • Spring Cloud
    • Spring Cloud Alibaba
  • RabbitMQ
  • RocketMQ
  • Kafka
  • MySQL8.0详解
  • Redis从入门到高可用
  • Elastic Stack
  • 操作系统
  • 计算机网络
  • 数据结构与算法
  • 云原生
  • Devops
  • 前端
  • 实用工具
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
  • Reference
GitHub (opens new window)
  • CSS3浮动定位与背景样式

  • CSS动画

  • JS基础语法与表达式

  • 流程控制语句与数组

  • JS函数与DOM

  • 面向对象

  • 正则表达式

  • ES6基础入门

    • 01-初识ES6
    • 02-模板字符串和箭头函数
    • 03-解构赋值
      • 什么是解构赋值
      • 数组解构赋值的原理
      • 解构赋值的默认值
      • 数组解构赋值的应用
        • 常见类数组的解构赋值
        • 函数参数的解构赋值
        • 交换变量的值
      • 对象解构赋值的原理
      • 对象解构赋值的注意事项
      • 对象解构赋值的应用
    • 04-对象字面量的增强与函数参数的默认值
  • ES6语法扩展

  • Promise与Class

  • Module与Babel

  • 前端
  • ES6基础入门
CodeAshen
2023-02-10
目录

03-解构赋值

# 数组的解构赋值

# 什么是解构赋值

结构赋值:解析某一数据的结构,将我们想要的东西提取出来,赋值给变量或常量。

const arr = [1, 2, 3];
const a = arr[0];
const b = arr[1];
const c = arr[2];
console.log(a, b, c);

// 解构赋值
const [a, b, c] = [1, 2, 3];
console.log(a, b, c);
1
2
3
4
5
6
7
8
9

# 数组解构赋值的原理

  • 模式(结构)匹配,即两边都是数组结构
  • 索引值相同的完成赋值
// 1.模式(结构)匹配
[] = [1, 2, 3];

// 2.索引值相同的完成赋值
const [a, b, c] = [1, 2, 3];
console.log(a, b, c);

// 不取的,可以直接用逗号跳过
const [a, [, , b], c] = [1, [2, 4, 5], 3];
console.log(a, b, c);
1
2
3
4
5
6
7
8
9
10

# 解构赋值的默认值

// 1.默认值的基本用法
const [a, b] = [];
console.log(a, b);    // undefined undefined

const [a = 1, b = 2] = [];
console.log(a, b);    // 1 2
1
2
3
4
5
6

只有当一个数组成员严格等于(===)undefined 时,对应的默认值才会生效。

// 默认值不生效
const [a = 1, b = 2] = [3, 0];
const [a = 1, b = 2] = [3, null];

// b 默认值生效
const [a = 1, b = 2] = [3];
1
2
3
4
5
6

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

const func = () => {
  console.log('我被执行了');
  return 2;
};

// 这种情况用不到默认值,func 函数不会执行
const [x = func()] = [1];

// 这种情况会取默认值,func 函数执行
const [x = func()] = [];
1
2
3
4
5
6
7
8
9
10

# 数组解构赋值的应用

# 常见类数组的解构赋值

对于常见的类数组的结构赋值,这里要注意类数组不是真正的数组,不能调用数组的方法。

(1)arguments

// arguments 只存在于非箭头函数,表示参数列表
function func() {
  const [a, b] = arguments;
  console.log(a, b);
}

func(1, 2);
1
2
3
4
5
6
7

(2)NodeList

// NodeList 存放了按条件筛选出的元素
const [p1, p2, p3] = document.querySelectorAll('p');
console.log(p1, p2, p3);
1
2
3

# 函数参数的解构赋值

数组结构赋值还常用于函数形参上。以求数组中两个元素的和为例:

// 不使用解构
const add1 = arr => arr[0] + arr[1];

// 使用解构
const add2 = ([x = 0, y = 0]) => x + y;

const array = [3, 4];
add1(array);
add2(array)
1
2
3
4
5
6
7
8
9

# 交换变量的值

原来交换两个变量的值,需要借助临时变量。

let x = 1;
let y = 2;

// 借助临时变量交换两个变量的值
let tmp = x;
x = y;
y = tmp;
console.log(x, y);
1
2
3
4
5
6
7
8

现在使用解构赋值可以不借助临时变量,一行代码搞定。

[x, y] = [y, x];
1

# 对象的解构赋值

# 对象解构赋值的原理

  • 模式(结构)匹配,两边都是对象结构
  • 属性名相同的完成赋值
// 属性名匹配即可,不需要按顺序
const { age, username } = { 
  username: 'Alex', 
  age: 18 
};

console.log(age, username);
1
2
3
4
5
6
7

其实对象的结构赋值的完整写法是这样的:

const { age: age, username: username } = { 
  username: 'Alex', 
  age: 18 
};

console.log(age, username);
1
2
3
4
5
6

根据这个,就可以理解对象结构赋值中取别名的用法了:

const { age: age, username: uname } = { 
  username: 'Alex', 
  age: 18 
};

console.log(age, uname);
1
2
3
4
5
6

# 对象解构赋值的注意事项

  • 对象解构赋值的默认值
  • 将一个已经声明的变量用于解构赋值
  • 可以取到继承的属性

(1)默认值

对象的属性值严格等于 undefined 时,对应的默认值才会生效

const { username = 'ZhangSan', age = 0 } = { 
    username: 'alex' 
};

console.log(username, age);  // alex 0
1
2
3
4
5

(2)默认值表达式

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

(3)将一个已经声明的变量用于解构赋值

如果将一个已经声明的变量用于对象的解构赋值,整个赋值需在圆括号中进行。

let x = 2;

// 错误写法,浏览器会误认为前面的花括号是镖师一个代码块
// { x } = { x: 1 }

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

console.log(x);
1
2
3
4
5
6
7
8
9

(4)以取到继承的属性

// 获取继承的 toString 方法, 解构赋值
const { toString } = {};

console.log(toString);
1
2
3
4

# 对象解构赋值的应用

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

// 不使用解构,形参为一个对象 user
const userInfo1 = user => 
  console.log(user.username, user.age);

// 用解构来接收对象参数
const userInfo2 = ({ age = 0, username = 'ZhangSan' }) =>
  console.log(username, age);

userInfo1({ username: 'alex', age: 18 });
userInfo2({ username: 'alex'});
1
2
3
4
5
6
7
8
9
10

(2)复杂的嵌套

const obj = {
  x: 1,
  y: [2, 3, 4],
  z: {
    a: 5,
    b: 6
  }
};

// const { x, y, z } = obj;
// console.log(x, y, z);

const {
  y,
  y: [, yy],
  z,
  z: { b }
} = obj;

console.log(yy, y, z, b);
/*
  yy == 3
  y == [2, 3, 4]
  z == { a: 5, b: 6 }
  b == 6
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 其他数据类型的解构赋值

(1)字符串的解构赋值

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

数组形式可以获取对象下标的字符。

// 数组形式的解构赋值
const [a, b, , , c] = 'hello';
console.log(a, b, c);    // h e o
1
2
3

对象形式除了可以获取对应下标的字符,还可以获取数组的其他属性,比如 length。

// 对象形式的解构赋值
const { 0: a, 1: b, length } = 'hello';

console.log(a, b, length);  // h e 5
1
2
3
4

(2)数值和布尔值的解构赋值

数值和布尔值在解构赋值时,会先将其转换为对应的包装对象,再按照对象的形式进行解构赋值。

// 数值解构赋值相当会右边是 new Number(123)
const { a, toString } = 123;
console.log(a, toString);  // a 为 undefined,toString 取到继承的属性

// 布尔值也类似
const { b = 2, toString } = true;
console.log(b, toString);  // b 取默认值 2,toString 为继承的属性
1
2
3
4
5
6
7

(3)undefined 和 null 的解构赋值

由于 undefined 和 null 都没有对应的包装对象,无法转为对象,所以对它们进行解构赋值,都会报错。

编辑 (opens new window)
上次更新: 2023/06/04, 12:34:19
02-模板字符串和箭头函数
04-对象字面量的增强与函数参数的默认值

← 02-模板字符串和箭头函数 04-对象字面量的增强与函数参数的默认值→

最近更新
01
第01章-RabbitMQ导学
02-10
02
第02章-入门RabbitMQ核心概念
02-10
03
第03章-RabbitMQ高级特性
02-10
更多文章>
Theme by Vdoing | Copyright © 2020-2023 CodeAshen | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式