前言

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

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

解构赋值

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

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

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

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

数组的解构赋值

为变量赋值。

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

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

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

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

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

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

数组解构

有几种情况

  • 成功解构

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

注意:

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

默认值

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

注意:

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

对象的解构赋值

对象解构

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

注意:

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

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

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

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

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

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

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

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

  1. // 多重嵌套,还可以嵌套数组
  2. let obj = {
  3. sample: [
  4. 'Hello',
  5. { sample1: 'World' }
  6. ]
  7. };
  8. let { sample: [sample, { sample1 }] } = obj;
  9. console.log(sample,sample1); // Hello World
  10. // 或者像这样?给数组或对象添加新内容
  11. let obj = {};
  12. let arr = [];
  13. ({ sample: obj.a, sample1: arr[0] } = { sample: 123, sample1: true });
  14. console.log(obj); // {a: 123}
  15. console.log(arr); // [true]

默认值

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

注意

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

注意

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

字符串的解构赋值

字符串也可以解构赋值。

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

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

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

数值和布尔值的解构赋值

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

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

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

函数参数的解构赋值

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

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

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

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

圆括号问题

什么是圆括号问题呢?

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

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

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

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

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

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

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

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

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

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

解构赋值的用途

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

  1. 交换变量的值

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

  1. // 数组的解构赋值
  2. let sample1 = 2;
  3. let sample2 = 4;
  4. [sample1, sample2] = [sample2, sample1];
  5. console.log(sample1, sample2); // 4 , 2
  1. 函数多个返回值的解构赋值
  1. // 解构函数返回的对象
  2. function sample() {
  3. return [1, 2, 3];
  4. }
  5. let [sample1, sample2, sample3] = sample();
  6. console.log(sample1, sample2, sample3); // 1, 2, 3
  7. // 解构函数返回的对象
  8. function sample() {
  9. return {
  10. sample11: 1,
  11. sample12: 2,
  12. sample13: 3,
  13. };
  14. }
  15. let {sample11, sample12, sample13} = sample();
  16. console.log(sample11, sample12, sample13); // 1, 2, 3
  1. 提取JSON数据

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

  1. let sampleJson = {
  2. id: 11,
  3. status: false,
  4. data: [{ name: 'name1' }, { name: 'name2' }]
  5. }
  6. let { id, status, data } = sampleJson;
  7. console.log(id, status, data);// 11, false, [{ name: 'name1' }, { name: 'name2' }]
  1. 输入模块的指定方法
  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. 前段之BOM ----DOM

    一.介绍 BOM(Browser Object Model)是指浏览器对象模型,它使 JavaScript 有能力与浏览器进行"对话". DOM (Document Object ...

  2. 前段--->js

    一,java script的引入方式 1,直接在script里书写你的代码 <script> alert("hbflfb")</script> 2,引入额外 ...

  3. 函数返回值为 const 指针、const 引用

    函数返回值为 const 指针,可以使得外部在得到这个指针后,不能修改其指向的内容.返回值为 const 引用同理. class CString { private: char* str; publi ...

  4. mysql锁场景及排查

    1.查询长时间不返回: 在表 t 执行下面的 SQL 语句: mysql> select * from t where id=1; 查询结果长时间不返回. 一般碰到这种情况的话,大概率是表 t ...

  5. 【UE4 C++】抛物线路径、发射轨道相关

    基于UGameplayStatics Blueprint_PredictProjectilePath_ByObjectType 根据 Object Type,算出抛物线的点集合和检测结果 static ...

  6. vue3.x移动端页面基于vue-router的路由切换动画

    移动端页面切换一般都具有动画,我们既然要做混合开发,做完之后还是不能看起来就像一个网页,所以我们基于vue-router扩展了一个页面切换push和pop的动画.这是一篇比较硬核的帖子,作者花了不少精 ...

  7. vue3.x移动端适配px2rem

    1.什么是px2rem px2rem是一个插件能将px自动转换为rem,以适配各种不同的屏幕尺寸.前端开发可以直接使用设计稿量出的尺寸或者蓝湖给出的px进行布局,这样极大的提高了开发效率. 2.前提条 ...

  8. csp-s 2021

    T1 廊桥分配 当一架飞机抵达机场时,可以停靠在航站楼旁的廊桥,也可以停靠在位于机场边缘的远机位. 乘客一般更期待停靠在廊桥,因为这样省去了坐摆渡车前往航站楼的周折. 然而,因为廊桥的数量有限,所以这 ...

  9. stm32电机控制之控制两路直流电机!看完你会了吗

    手头上有一个差分驱动的小车,使用两个直流电机驱动,要实现小车的在给定速度下运动,完成直线行驶,转向,加速,刹车等复杂运动. 使用的电机是12v供电的直流电机,带编码器反馈,这样就可以采用闭环速度控制, ...

  10. 一文带你掌握【TCP拥塞窗口】原理

    ❝ 关注公众号:高性能架构探索.后台回复[资料],可以免费领取 ❞ 学过网络相关课程的,都知道TCP中,有两个窗口: 滑动窗口(在我们的上一篇文章中有讲),接收方通过通告发送方自己的可以接受缓冲区大小 ...