前言

该篇笔记是第二篇 变量的解构赋值。

这一章原文链接: 变量的解构赋值

解构赋值

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

解构赋值是对赋值运算符的扩展。

这是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。

在代码书写上简洁且易读,语义更加清晰明了;也方便了复杂对象中数据字段获取。

数组的解构赋值

为变量赋值。

let sample1 = 1;
let sample2 = 2;
let sample3 = 3;

上面代码使用ES6的数组解构赋值可以写成下面这样。从数组中提取值,按照对应位置,对变量赋值。

let [sample1, sample2, sample3] = [1, 2, 3];
console.log(sample1, sample2, sample3); // 1, 2, 3

这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。

上面代码在声明变量同时进行了赋值,ES6也可以先声明变量再进行解构赋值,

let sample1, sample2, sample3;  // 先申明
[sample1, sample2, sample3] = [1, 2, 3];
console.log(sample1, sample2, sample3); // 1, 2, 3

数组解构

有几种情况

  • 成功解构

    • 完全解构赋值
    • 不完全解构赋值
    • 嵌套数组解构赋值
    • 变量声明并赋值解构
    • 先声明变量再进行解构赋值
  • 不成功解构

注意:

  • 数组形式解构赋值 等号右边必须为可遍历结构,也就是说具有 Iterator 接口的数据结构。
  • 数组形式解构赋值 需要按照对应位置,对对象赋值。
  • 数组形式解构赋值 不成功变量的值等于undefined
  • 数组形式解构赋值 的数组可以是多维数组。
  • 数组形式解构赋值 不用将等号右边的数组全部解构出来。
  • 数组形式解构赋值 允许等号左边模式不全部匹配等号右边的数组。
// 解构成功
let [sample1, [sample2, sample3]] = [1, [2, 3]];
console.log(sample1, sample2, sample3); // 1, 2, 3 // 解构不成功,变量的值就等于undefined。
let [sample] = []; // sample 的值为 undefined
let [sample1, sample2] = [1]; // sample2 的值为 undefined // 如果等号右边不是数组,也就是不可遍历结构,将会报错
let [sample] = 1; // 直接报错,因为等号右边的值是个字面量不可遍历
let sample1, sample2, sample3, sampleN;  // 先声明变量再进行解构赋值
[[sample1, sample2], sample3, ...sampleN] = [[1, 2], 3, 4, 5]; // 嵌套数组
console.log(sample1, sample2, sample3, sampleN); // 1 2 3 [4, 5] let [sample11, sample12] = [1, 2, 3]; // 变量声明并赋值解构
let [sample21, ,sample23] = [1, 2, 3];
console.log(sample11, sample12); // 不完全解构 1 2
console.log(sample21, sample23); // 不完全解构 1 3

默认值

当你不想从数组中解构出的值为undefined,解构赋值允许指定默认值。

注意:

  • 当一个数组成员严格等于undefined,默认值才会生效。
  • 默认值不一定为字面量,也可以引用解构赋值的其他变量,但该变量必须已声明。
  • 默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。
// 当 值 不存在时,默认值生效
let [sample1 = 10, sample2 = 11] = [2];
console.log(sample1, sample2); // 2 11 // 当 值 === undefined 时,默认值才会生效
let [sample10 = 10, sample11 = 11, sample13 = 12] = [undefined, "", null];
console.log(sample10, sample11, sample13); // 10, , null, let [sample21 = 1, sample22 = sample21] = [];
console.log(sample21, sample22);
let sample30 = 31;
let [sample31 = sample30, sample32 = 3] = [];
console.log(sample31, sample32);

对象的解构赋值

对象解构

数组的解构赋值与对象的解构赋值有很大区别

注意:

  • 对象的解构赋值不再和顺序有关,是与变量名有关,变量必须与属性同名,才能取到正确的值。
  • 对象的解构赋值是根据对象key值进行匹配。
  • 如果解构不成功,那么值为undefined
  • 和数组解构赋值一样,可以对嵌套结构的对象进行解构赋值。

表达式等号左右两边,都要有互相匹配的属性值,才能将右边匹配成功keyvalue值赋值给左边相对应keyvalue,左边的value值作为变量。

let { sample: sample, sample1: sample2 } = { sample: 10, sample1: 11 }
console.log(sample); // 10
console.log(sample1) // 报错 sample1 is not defined
console.log(sample2) // 11

ES6 对对象进行了扩展,对象里的属性与value值可以简写(以后会提到,目前只要知道可以这样用),

ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。

当属性名与值或方法名相同时,可以简写为一个。

const { log: log } = console; // 可以解构现有对象
log('hello'); // hello
// 上面代码可以简写为下面
const { log } = console;
log('hello') // hello

在嵌套的对象中使用解构赋值。

// 多重嵌套,还可以嵌套数组
let obj = {
sample: [
'Hello',
{ sample1: 'World' }
]
}; let { sample: [sample, { sample1 }] } = obj; console.log(sample,sample1); // Hello World // 或者像这样?给数组或对象添加新内容
let obj = {};
let arr = []; ({ sample: obj.a, sample1: arr[0] } = { sample: 123, sample1: true });
console.log(obj); // {a: 123}
console.log(arr); // [true]

默认值

和数组解构赋值默认值类似,对象的默认值

注意

  • 当一个对象的属性严格等于undefined,默认值才会生效。
  • 默认值不一定为字面量,也可以引用解构赋值的其他变量,但该变量必须已声明。
// 当 对象的属性值 不存在时,默认值生效
let {sample1 = 10, sample2 = 11} = {sample1:2};
console.log(sample1, sample2); // 2, 11 //当 对象的属性值 === undefined 时,默认值才会生效
let { sample10 = 10, sample11 = 11, sample12 = 12 } =
{ sample10: "", sample11: undefined, sample12: null };
console.log(sample10, sample11, sample12); // 11, , null // 默认值为变量
let {sample21 = 1, sample22 = sample21} = {};
console.log(sample21, sample22); // 1, 1 let sample30 = 31;
let {sample31 = sample30, sample32 = 3} = {};
console.log(sample31, sample32); // 31, 3

注意

  1. 如果要将一个已经声明的变量用于解构赋值,必须非常小心。
  2. 解构赋值允许等号左边的模式之中,不放置任何变量名。
  3. 由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。
// 1. 语法错误
let sample;
{sample:sample} = {sample: 1}; // 直接报错
/*
因为 JavaScript 引擎会将{sample}理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。
*/ // 2. 虽然无意义但是合法
({} = [true, false]);
({} = 'abc');
({} = []); // 3. 数组使用对象的解构赋值,
let { 0: sample0, 1: sample1 } = [1, 2];
console.log(sample0, sample1); // 1, 2

字符串的解构赋值

字符串也可以解构赋值。

当字符串进行解构赋值的时候,字符串被转换成了一个类数组。

类数组也有length属性,所以还可以通过这个方式获取字符串的长度

let { length } = 'sample';
console.log(length); // 6

数值和布尔值的解构赋值

解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。

由于**undefined****null**无法转为对象,所以对它们进行解构赋值,都会报错。

// 数值与布尔值 进行解构赋值
let { toLocaleString: sampleNum } = 111;
console.log(sampleNum === Number.prototype.toLocaleString); let { toString: sampleBol } = true;
console.log(sampleBol === Boolean.prototype.toString); // undefined 和 null 进行解构赋值
let { prop: x } = undefined; // 直接报错 TypeError
let { prop: y } = null; // 直接报错 TypeError

函数参数的解构赋值

函数参数进行解构赋值,函数参数需要为可解构赋值的解构。

// 参数为数组时,参数在传入函数的时候,数组参数就被解构成变量 sample1 和 sample2 。
function addNumberArr([sample1, sample2]) {
return sample1 + sample2;
} console.log(addNumberArr([4, 4])); // 8 // 参数为对象时,函数通过对这个参数进行解构 得到变量 sample1 和 sample2 的值。
function addNumberObj({ sample1, sample2 }) {
return sample1 + sample2;
} console.log(addNumberObj({ sample1: 10, sample2: 20 })); // 30

函数参数的解构也可以使用默认值。

// 函数通过对这个参数进行解构,得到变量sample1和sample2的值。
// 如果解构失败,sample1和sample2等于默认值。 function sample({ sample1 = 0, sample2 = 0 } = {}) {
console.log([sample1, sample2])
return [sample1, sample2];
} sample({ sample1: 1, sample2: 2 }); // [1, 2]
sample({ sample1: 1 }); // [1, 0]
sample({}); // [0, 0]
sample(); // [0, 0]

圆括号问题

什么是圆括号问题呢?

原来在编译器中,无法在解析到等号之前识别一个式子为表达式还是解构赋值等号左边部分,也就是模式匹配中左边的key(属性)值。那么如果识别到了圆括号后,编译器该按照什么方式去处理圆括号呢?

ES6 规定,只要有可能导致解构的歧义,就不得使用圆括号。

阮一峰老师建议只要有可能,就不要在模式中放置圆括号。

注意:以下三种情况不能使用圆括号

  1. 变量声明语句
  2. 函数参数也属于变量声明,因此不能带有圆括号。
  3. 赋值语句的模式

上面三种情况使用圆括号直接报错。

// 1. 变量声明语句
let [(sample)] =[1]; // 直接报错
let { sample: ({ sample1: sample1 }) } = { sample: { sample1: 2 } }; // 直接报错 // 2. 函数参数也属于变量声明,因此不能带有圆括号。
function sampleFn([(sample)]) { return sample; } // 直接报错 // 3. 赋值语句的模式
({ sample2: sample21 }) = { sample2: 42 }; // 直接报错
[({ sample3: sample31 }), { sample4: sample41 }] = [{}, {}];

只有一种情况可以使用圆括号

不能有声明语句,赋值语句的非模式(属性名)部分,可以使用圆括号。

({ sample: (sample) } = {}); // 正确
console.log(sample); // undefined

解构赋值的用途

解构赋值主要还是用在对象和数组上,

  1. 交换变量的值

不用临时变量,怎么交换两个变量的值?可以使用解构赋值简单实现。

// 数组的解构赋值
let sample1 = 2;
let sample2 = 4;
[sample1, sample2] = [sample2, sample1];
console.log(sample1, sample2); // 4 , 2
  1. 函数多个返回值的解构赋值
// 解构函数返回的对象
function sample() {
return [1, 2, 3];
}
let [sample1, sample2, sample3] = sample();
console.log(sample1, sample2, sample3); // 1, 2, 3 // 解构函数返回的对象
function sample() {
return {
sample11: 1,
sample12: 2,
sample13: 3,
};
}
let {sample11, sample12, sample13} = sample();
console.log(sample11, sample12, sample13); // 1, 2, 3
  1. 提取JSON数据

可以使用解构赋值一次性提取多个数据

let sampleJson = {
id: 11,
status: false,
data: [{ name: 'name1' }, { name: 'name2' }]
}
let { id, status, data } = sampleJson;
console.log(id, status, data);// 11, false, [{ name: 'name1' }, { name: 'name2' }]
  1. 输入模块的指定方法
const { SourceMapConsumer, SourceNode } = require("source-map"); // 示例代码

ES6学习 第二章 变量的解构赋值的更多相关文章

  1. ES6学习笔记之变量的解构赋值

    变量的解构赋值 ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构. 数组的解构赋值 以前,为变量赋值,只能直接指定值: 1 2 3 var a = 1; var b = 2; ...

  2. es6学习2:变量的解构赋值

    一:数组的解构赋值 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构 let [foo, [[bar], baz]] = [1, [[2], 3]]; foo bar ba ...

  3. ES6 第三章 变量的解构赋值 具体参照http://es6.ruanyifeng.com

    1.基本用法 let [a, b, c] = [1, 2, 3];左右两边解构格式要保持一致. 2.默认值 let [x, y = 'b'] = ['a']; // x='a', y='b' let ...

  4. ES6学习----let、const、解构赋值、新增字符串、模板字符串、Symbol类型、Proxy、Set

    这篇es6的学习笔记来自于表哥 表严肃,是我遇到过的讲课最通透,英文发音最好听的老师,想一起听课就去这里吧 https://biaoyansu.com/i/hzhj1206 ES6就是JS6,JS的第 ...

  5. ES6 学习笔记(二)解构赋值

    一.数组的解构赋值 1.基本用法 ES6允许按照一定模式从数组和对象中提取值,然后对变量进行赋值,该操作即为解构 如: let [a,b,c]=[1,2,3]; console.log(a,b,c) ...

  6. ES6学习笔记(2)----变量的解构和赋值

    参考书<ECMAScript 6入门>http://es6.ruanyifeng.com/ 变量的解构和赋值 本质上:只要模式匹配,左边的变量就能被赋予右边对应的值 原则: 解构赋值的规则 ...

  7. ES6标准入门之变量的解构赋值简单解说

    首先我们来看一看解构的概念,在ES6标准下,允许按照一定模式从数组和对象中提取值,然后对变量进行赋值,这被称作解构,简而言之粗糙的理解就是变相赋值. 解构赋值的规则是,只要等号右边的值不是对象或者数组 ...

  8. ES6系列_3之变量的解构赋值

    ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构. 解构有三种类型: 1.数组的解构赋值 (1)简单的数组解构 以前,我们给变量赋值是直接单个指定值,比如: let a=0; ...

  9. ES6学习随笔--字符串模板、解构赋值、对象、循环、函数、Promise、Generrator

    在线编译器:babel.github 在nongjs中使用 'use strict' let a = ; 运行node : node --harmony_destructuring xxx.js 代码 ...

随机推荐

  1. 从0到1使用Kubernetes系列(二):安装工具介绍

    该系列第一篇为:<从0到1使用Kubernetes系列--Kubernetes入门>.本文是Kubernetes系列的第二篇,将介绍使用Kubeadm+Ansible搭建Kubernete ...

  2. FastAPI 学习之路(十四)响应模型

    系列文章: FastAPI 学习之路(一)fastapi--高性能web开发框架 FastAPI 学习之路(二) FastAPI 学习之路(三) FastAPI 学习之路(四) FastAPI 学习之 ...

  3. 7-Zip

    7-Zip https://www.7-zip.org/

  4. C++ 与 Visual Studio 2019 和 WSL(四)——库组件

    C++ 与 Visual Studio 2019 和 WSL (库组件) Reference 在 C++ 项目中使用库和组件 | Microsoft Docs 演练:创建和使用自己的动态链接库 (C+ ...

  5. 类图示例-订单系统 / Class Diagram - Order System

    类图示例-订单系统 / Class Diagram - Order System 什么是类图? 类图通过显示它的类和它们之间的关系来概述系统.类图是静态的 - 它们显示交互的内容,但不显示交互时会发生 ...

  6. Java:并发笔记-02

    Java:并发笔记-02 说明:这是看了 bilibili 上 黑马程序员 的课程 java并发编程 后做的笔记 3. 共享模型之管程-1 本章内容-1 共享问题 synchronized 线程安全分 ...

  7. OO第四单元

    OO第四单元总结 第四单元架构设计 第一次作业 uml类图 这次作业我采取的基本思路就是根据指令来建造一个简易的类图,用于查询,其中umlclass中包含了umlAttraibute,umlOpera ...

  8. 简明教程 | Docker篇 · 其一:基础入门

    了解Docker Docker是什么 Docker是指容器化技术,用于支持创建和使用 Linux 容器,同时Docker也是软件容器平台. 什么是容器(container) 容器是主机上与其他进程隔离 ...

  9. Python学习笔记总结

    目录 Python学习笔记总结 前言 安装 数据类型 Hello,World 变量 字符串 首字母大写 全部小写 全部大写 Tab和换行符 格式化 去除空格 List列表 列表增删改查排序 遍历列表 ...

  10. Linux安装部署Zabbix

    Zabbix 是一个企业级的分布式开源监控方案,能够监控各种网络参数以及服务器健康性和完整性的软件.Zabbix使用灵活的通知机制,允许用户为几乎任何事件配置基于邮件的告警.这样可以快速反馈服务器的问 ...