文章目录

  • 前言
  • 一、解构赋值概述
  • 二、数组模型的解构赋值
  • 二、对象的解构赋值
  • 三、可嵌套可忽略
  • 四、解构默认值
  • 五、不完全解构
  • 六、剩余运算符
  • 七、注意事项
  • 八、字符串的解构赋值
  • 九、圆括号问题
  • 总结

前言

本文主要讲解了解构赋值的概念、数组模型的解构赋值、对象的解构赋值等知识点,以及圆括号的注意事项。

一、解构赋值概述

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

解构赋值是对赋值运算符的扩展。是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。在代码书写上简洁且易读,语义更加清晰明了,也方便了复杂对象中数据字段获取。

二、数组模型的解构赋值

以前,为变量赋值,只能直接指定值。

var a = 1;
var b = 2;
var c = 3;

而 ES6 允许写成下面这样:

var [a, b, c] = [1, 2, 3];
// a = 1
// b = 2
// c = 3

实例

步骤一:新建一个名为 test.js 的文件,在其中输入以下代码:

var [a, b, c] = [1, 2, 3];
console.log("a 的值为" + a);
console.log("b 的值为" + b);
console.log("c 的值为" + c);

步骤二:在终端里面输入以下命令:

node test.js

我们会看到以下效果:

上面代码表示,可以从数组中提取值,按照对应位置,对变量赋值。本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。下面是一些进行解构的例子。

可嵌套

let [a, [[b], c]] = [1, [[2], 3]];
// a = 1
// b = 2
// c = 3

实例

步骤一:新建一个名为 test1.js 的文件,在其中输入以下代码:

let [a, [[b], c]] = [1, [[2], 3]];
console.log("a 的值为" + a);
console.log("b 的值为" + b);
console.log("c 的值为" + c);

步骤二:在终端里面输入以下命令:

node test1.js

我们会看到以下效果:

可忽略

let [x, , y] = [1, 2, 3];
// x = 1
// y = 3

实例

步骤一:新建一个名为 test2.js 的文件,在其中输入以下代码:

let [x, , y] = [1, 2, 3];
console.log("x 的值为" + x);
console.log("y 的值为" + y);

步骤二:在终端里面输入以下命令:

node test2.js

我们会看到以下效果:

剩余运算符

let [a, ...b] = [1, 2, 3];
//a = 1
//b = [2, 3]

实例

步骤一:新建一个名为 test3.js 的文件,在其中输入以下代码:

let [a, ...b] = [1, 2, 3];
console.log("a 的值为" + a);
console.log("b 的值为" + b);

步骤二:在终端里面输入以下命令:

node test3.js

我们会看到以下效果:

不完全解构

不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。

let [a = 1, b] = [];
// a = 1, b = undefined

如果解构不成功,变量的值就等于 undefined,示例代码:

步骤一:新建一个名为 test4.js 的文件,在其中输入以下代码:

let [a = 1, b] = [];
console.log("a 的值为" + a);
console.log("b 的值为" + b);

步骤二:在终端里面输入以下命令:

node test4.js

我们会看到以下效果:

解构默认值

let [a = 2] = [undefined];
console.log("a 的值为" + a);
// a = 2

新建文件 demo.js 添加以上代码并在终端使用 node 命令运行:

当解构模式有匹配结果,且匹配结果是 undefined 时,会触发默认值作为返回结果。

let [a = 3, b = a] = [];
// a = 3, b = 3let [c = 3, d = c] = [1];
// c = 1, d = 1let [e = 3, f = e] = [1, 2];
// e = 1, f = 2

示例代码:

步骤一:新建一个名为 test5.js 的文件,在其中输入以下代码:

console.log("示例一:");
console.log("a 与 b 匹配结果为 undefined,触发默认值:a = 3; b = a =3");
let [a = 3, b = a] = [];
console.log("a 的值为" + a);
console.log("b 的值为" + b);console.log("示例二:");
console.log("c 正常解构赋值,匹配结果:c = 1,d 匹配结果 undefined,触发默认值:d = c =1"
);
let [c = 3, d = c] = [1];
console.log("c 的值为" + c);
console.log("d 的值为" + d);console.log("示例三:");
console.log("e 与 f 正常解构赋值,匹配结果:e = 1,f = 2。");
let [e = 3, f = e] = [1, 2];
console.log("e 的值为" + e);
console.log("f 的值为" + f);

在终端使用 node 命令运行:

二、对象的解构赋值

解构不仅可以用于数组,还可以用于对象。对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
// foo = 'aaa'
// bar = 'bbb'let { baz : foo } = { baz : 'ddd' };
// foo = 'ddd'let person = { name: 'zhangsan', age: 20, sex: '男'};
let {name, age, sex} = person;
// name = 'zhangsan'
// age = 20
// sex = '男'

示例代码:

步骤一:新建一个名为 test6.js 的文件,在其中输入以下代码:

console.log("示例一:");
console.log("等号左边的两个变量的次序,与等号右边两个同名属性的次序不一致,但是对取值完全没有影响。"
);
let { foo, bar } = { foo: "aaa", bar: "bbb" };
console.log("foo 的值为" + foo);
console.log("bar 的值为" + bar);console.log("示例二:");
let { baz: ccc } = { baz: "ddd" };
console.log("ccc 的值为" + ccc);console.log("示例三:");
let person = { name: "zhangsan", age: 20, sex: "男" };
let { name, age, sex } = person;
console.log("name :" + name);
console.log("age :" + age);
console.log("sex :" + sex);

在终端使用 node 命令运行:

下面这个例子的变量没有对应的同名属性,导致取不到值,最后等于 undefined。

var { baz } = { foo: "aaa", bar: "bbb" };
// baz = undefined

新建 index.html 文件,示例代码:

<!--index.html-->
<!DOCTYPE html>
<html><head></head><body><script>var { baz } = { foo: "aaa", bar: "bbb" };document.write("baz 的值为" + baz);</script></body>
</html>

显示效果:

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

var { foo: baz } = { foo: 'aaa', bar: 'bbb' };
// baz = "aaa"let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
// f = 'hello'
// l = 'world'

三、可嵌套可忽略

和数组一样,解构也可以用于嵌套结构的对象。

let obj = {p: ['hello', {y: 'world'}] };
let {p: [x, { y }] } = obj;
// x = 'hello'
// y = 'world'let obj = {p: ['hello', {y: 'world'}] };
let {p: [x, {  }] } = obj;
// x = 'hello'

示例代码一:

新建一个名为 index1.html 的文件,在其中输入以下代码:

<!DOCTYPE html>
<html><head></head><body><script>let obj = { p: ["hello", { y: "world" }] };let {p: [x, { y }],} = obj;document.write("x 的值为" + x + "</br>");document.write("y 的值为" + y);</script></body>
</html>

显示效果:

示例代码二:

新建一个名为 index2.html 的文件,在其中输入以下代码:

<!DOCTYPE html>
<html><head></head><body><script>let obj = { p: ["hello", { y: "world" }] };let {p: [x, {}],} = obj;document.write("x 的值为" + x);</script></body>
</html>

显示效果:

下面是嵌套赋值的例子。

let obj = {};
let arr = [];({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true });//obj = {prop:123}
//arr = [true]

四、解构默认值

对象的解构也可以指定默认值。

let {a = 10, b = 5} = {a: 3};
// a = 3; b = 5;let {c: aa = 10, d: bb = 5} = {c: 3};
// aa = 3; bb = 5;var { message: msg = 'Something went wrong' } = {};
//msg = "Something went wrong"

示例代码:

步骤一:新建一个名为 test7.js 的文件,在其中输入以下代码:

console.log("示例一:");
let { a = 10, b = 5 } = { a: 3 };
console.log("a 的值为" + a);
console.log("b 的值为" + b);console.log("示例二:");
let { c: aa = 10, d: bb = 5 } = { c: 3 };
console.log("aa 的值为" + aa);
console.log("bb 的值为" + bb);console.log("示例三:");
var { message: msg = "Something went wrong" } = {};
console.log("msg 的值为" + msg);

步骤二:在终端使用 node 命令运行:

五、不完全解构

let obj = {p: [{y: 'world'}] };
let {p: [{ y }, x ] } = obj;
// x = undefined
// y = 'world'

示例代码:

步骤一:新建一个名为 test8.js 的文件,在其中输入以下代码:

let obj = { p: [{ y: "world" }] };
let {p: [{ y }, x],
} = obj;
console.log("x =" + x);
console.log("y =" + y);

步骤二:在终端使用 node 命令运行:

六、剩余运算符

let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40};
// a = 10
// b = 20
// rest = {c: 30, d: 40}

示例代码:

步骤一:新建一个名为 test9.js 的文件,在其中输入以下代码:

let { a, b, ...rest } = { a: 10, b: 20, c: 30, d: 40 };
console.log("a =" + a);
console.log("b =" + b);
console.log("rest =" + rest.c);
console.log("rest =" + rest.d);

步骤二:在终端使用 node 命令运行:

七、注意事项

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

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

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

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

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

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

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

八、字符串的解构赋值

在数组的解构中,解构的目标若为可遍历对象,皆可进行解构赋值。

字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。新建文件 index3.html ,示例代码:

<!DOCTYPE html>
<html><head></head><body><script>let [a, b, c, d, e] = "hello";document.write("a 的值为" + a + "</br>");document.write("b 的值为" + b + "</br>");document.write("c 的值为" + c + "</br>");document.write("d 的值为" + d + "</br>");document.write("e 的值为" + e);</script></body>
</html>

显示效果:

类似数组的对象都有一个 length 属性,因此还可以对这个属性解构赋值。新建文件 index4.html ,示例代码:

<!DOCTYPE html>
<html><head></head><body><script>let { length: len } = "hello";document.write("len =" + len);</script></body>
</html>

显示效果:

九、圆括号问题

解构赋值虽然很方便,但是解析起来并不容易。对于编译器来说,一个式子到底是模式,还是表达式,没有办法从一开始就知道,必须解析到(或解析不到)等号才能知道。

由此带来的问题是,如果模式中出现圆括号怎么处理。ES6 的规则是,只要有可能导致解构的歧义,就不得使用圆括号。但是,这条规则实际上不那么容易辨别,处理起来相当麻烦。因此,建议只要有可能,就不要在模式中放置圆括号。

不得使用圆括号的情况

变量声明语句中,不能带有圆括号。

var [(a)] = [1];var {x: (c)} = {};
var ({x: c}) = {};
var {(x: c)} = {};
var {(x): c} = {};var { o: ({ p: p }) } = { o: { p: 2 } };

上面三个语句都会报错,因为它们都是变量声明语句,模式不能使用圆括号。

函数参数中,模式不能带有圆括号。

function f([(z)]) { return z; }

函数参数也属于变量声明,因此不能带有圆括号,否则报错。

赋值语句中,不能将整个模式,或嵌套模式中的一层,放在圆括号之中。

({ p: a }) = { p: 42 };
([a]) = [5];
// 上面代码将整个模式放在圆括号之中,导致报错。[({ p: a }), { x: c }] = [{}, {}];
// 上面代码将嵌套模式的一层,放在圆括号之中,导致报错。

可以使用圆括号的情况

可以使用圆括号的情况只有一种:赋值语句的非模式部分,可以使用圆括号。

[(b)] = [3];                // 正确
({ p: (d) } = {});          // 正确
[(parseInt.prop)] = [3];    // 正确

上面三行语句都可以正确执行,因为首先它们都是赋值语句,而不是声明语句;其次它们的圆括号都不属于模式的一部分。第一行语句中,模式是取数组的第一个成员,跟圆括号无关;第二行语句中,模式是 p,而不是 d;第三行语句与第一行语句的性质一致。

总结

  • 解构赋值就是把数据结构分解,然后给变量进行赋值;
  • 如果结构不成功,变量跟数值个数不匹配的时候,变量的值为 undefined;
  • 数组解构用中括号包裹,多个变量用逗号隔开,对象解构用花括号包裹,多个变量用逗号隔开;
  • 利用解构赋值能够让我们方便的去取对象中的属性跟方法。

下文讲解ES6 Map 与 Set。

ES6 入门—ES6 解构赋值相关推荐

  1. ES6新语法--解构赋值

    对象解构赋值 ※很重要 /*** 对象解构赋值:获取元素中属性的值,然后赋值给变量*///声明一个对象 let obj = {name:'chen',age:38,gender:'man',score ...

  2. ES6变量的解构赋值--对象篇

    目录 使用方式 普通形式 嵌套结构 使用默认值 注意事项 上一篇我们讲解了数组的解构赋值,解构还可以用于对象.字符串等等,这里我们来讲解对象的解构赋值. ES6变量的解构赋值--数组_zxn20012 ...

  3. (34)2021-02-24(ES6变量的解构赋值)

    ES6变量的解构赋值 一. 变量的解构赋值 1.什么是解构 2.数组解构赋值 不完全解构 3.对象解构赋值 方法解构 注意点 4.字符串解构 5.函数参数的解构赋值 6.用途 6.1 交换变量的值 6 ...

  4. 【ES6(2015)】解构赋值Desctructuring

    文章目录 1. 数组解构赋值 2. 对象解构赋值 3. 字符串解构赋值 在 ES6 中新增了变量赋值的方式:解构赋值.允许按照一定模式,从数组和对象中提取值,对变量进行赋值.如果对这个概念不了解,我们 ...

  5. ES6 数组的解构赋值

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

  6. ES6——变量的解构赋值

    ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构. let [a, b] = [1, 2]; let {c, d} = {c: 3, d: 4};console.log(a ...

  7. 阮一峰 / ES6 数组的解构赋值

    目录 一.定义 二.详情讲解 1.数组解构:数组解构时数组的元素是按次序排列的,变量的取值由它的位置决定 2.对象解构:对象解构时对象的属性没有次序,变量必须与属性同名,才能取到正确的值. 三.用途 ...

  8. Vue学习笔记(三)Vue2三种slot插槽的概念与运用 | ES6 对象的解构赋值 | 基于Vue2使用axios发送请求实现GitHub案例 | 浏览器跨域问题与解决

    文章目录 一.参考资料 二.运行环境 三.Vue2插槽 3.1 默认插槽 3.2 具名插槽 3.3 作用域插槽 ES6解构赋值概念 & 作用域插槽的解构赋值 3.4 动态插槽名 四.GitHu ...

  9. ES6数组的解构赋值( 中)

    数组的解构赋值的用法有以下几情况要注意: 1.结构赋值可以嵌套的 数组的解构赋值的用法有以下几情况要注意:1.结构赋值可以嵌套的 var [ a,b,[ c1,c2 ] ] = [ 1,2,[ 3.1 ...

  10. es6—变量的解构赋值

    数组的解构赋值 /* 1.变量的解构赋值: * 数组的元素是按次序排列的,变量的取值由它的位置决定: * 从数组和对象中提取值,对变量进行赋值,这被称为解构; * 属于"模式匹配" ...

最新文章

  1. sap可以指定应用服务器,SAP扫盲系列之一:什么是SAP系统和应用服务器
  2. cocos2d-x android 移植 问题
  3. Jupyter notebook运行指定的conda虚拟环境
  4. H3C 交换机S6520X软件版本升级
  5. 数学问题——最大公约数与最小公倍数
  6. linux桌面创建文档,有没有可以创建.desktop文件的GUI应用程序?
  7. qt 3d迷宫游戏_Steam上最硬核的恐怖游戏?玩家耗时一个月才通第一关!
  8. 二叉树的建立和遍历算法 - 数据结构和算法47
  9. 数据结构---邻接矩阵的BFS
  10. Apache logresolve命令
  11. php limit offset 1,laravel自定义分页的实现案例offset()和limit()
  12. 通达信指标大全_选股指标:通达信指标大全,筹码起爆最佳的信号抄底位置
  13. 霍尔增量式编码器左右车轮线速度的计算
  14. 数字化成熟度评估模型一文读尽
  15. mysql写保护,sd卡有写保护怎么格式化
  16. python学习笔记9——第八章 异常
  17. 《中国垒球协会》:新春贺词
  18. 天津出差系列(一)----第一天
  19. 如何避免用户“漫天要价”和“就地还钱”
  20. 最简陋的MP3播放器

热门文章

  1. 千年虫,2038年虫
  2. “任务管理器”中的系统进程
  3. RAM生成和调用(ISE)
  4. 【转】推荐五款支持外链的免费网盘
  5. iOS小技能:lldb打印block参数签名( Python script for lldb that prints an Objective-C block signature)
  6. 谷歌Google搜索引擎对302跳转会不会传递权重?
  7. python flask简单使用
  8. LUA 和 JAVA 的区别
  9. 小微企业如何实现数字化转型?应该从哪一步开始?
  10. 2016 最新开发者账号 · 邓白氏申请申请流