ES6为对象和数组都添加了解构功能,将数据解构打散的过程变得更简单,可以从打散后更小的部分中获取所需信息。

对象解构

let node = {
type: "Identifier",
name: "foo"
}; let {type, name} = node; console.log(type); // "Identifier"
console.log(name); // "foo"

解构赋值

let node = {
type: "Identifier",
name: "foo"
},
type = "Literal",
name = 5; // 使用解构语法为多个变量赋值
// 注意:这里要在表达式的外层套一对小括号,否则{}会被视为一个代码块
({type, name} = node); console.log(type); // "Identifier"
console.log(name); // "foo"

解构表达式的值与表达式右侧(也就是=右侧)的值相等。

let node = {
type: "Identifier",
name: "foo"
},
type = "Literal",
name = 5; function outputInfo(value) {
console.log(value === node); // true
} // 调用方法的同时使用解构表达式赋值
// 表达式的值为等号(=)右侧的值
outputInfo({type, name} = node); console.log(type); // "Identifier"
console.log(name); // "foo"

默认值

使用解构表达式时,如果指定的局部变量名称在对象中不存在,name这个局部变量会被赋值为 undefined。

let node = {
type: "Identifier",
name: "foo"
}; let { type, name, value } = node; console.log(type); // "Identifier"
console.log(name); // "foo"
console.log(value); // undefined

也可以为不存在的局部变量定义默认值。

只有当解析对象中没有该属性或该属性值为undefined时,默认值才会生效。

let node = {
type: "Identifier",
name: "foo"
}; let { type, name, value = true } = node; console.log(type); // "Identifier"
console.log(name); // "foo"
console.log(value); // true

为非同名变量赋值

let node = {
type: "Identifier",
name: "foo"
}; // 使用解构语法为多个变量赋值
let {type: localType, name: localName} = node; console.log(localType); // "Identifier"
console.log(localName); // "foo"

写法同对象字面量的语法相反,值在左边,变量在右边。

也可以在为非同名变量赋值的同时为其赋默认值。

let node = {
type: "Identifier"
}; // 使用解构语法为多个变量赋值
let {type: localType, name: localName = "bar"} = node; console.log(localType); // "Identifier"
console.log(localName); // "bar"

嵌套对象解构

解构嵌套对象仍然与对象字面量的语法相似。

let node = {
type: "Identifier",
name: "foo",
loc: {
start: {
line: 1,
column: 1
},
end: {
line: 1,
column: 4
}
}
}; let { loc: { start } } = node; console.log(start.line); // 1
console.log(start.column); // 1

上例在解构模式中使用了花括号,其含义为在找到node对象中的loc属性后,应当深入一层继续查找start属性。

所有冒号前的标识符都代表在对象中的检索位置,其右侧为被赋值的变量名;

如果冒号后是花括号,则意味着要赋予的最终值嵌套在对象内部更深的层级中。

也可以使用一个与对象属性名不同的局部变量名。

let node = {
type: "Identifier",
name: "foo",
loc: {
start: {
line: 1,
column: 1
},
end: {
line: 1,
column: 4
}
}
}; let { loc: { start: localStart } } = node; console.log(localStart.line); // 1
console.log(localStart.column); // 1

数组解构

数组解构使用的是数组字面量,且解构操作全部在数组内完成。

let colors = [ "red", "green", "blue" ];
let [ firstColor, secondColor ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"

省略部分元素,只为感兴趣的元素提供变量名

let colors = [ "red", "green", "blue" ];
let [ , , thirdColor ] = colors;
console.log(thirdColor); // "blue"

解构赋值

let colors = [ "red", "green", "blue" ],
firstColor = "black",
secondColor = "purple";
[ firstColor, secondColor ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"

使用数组解构交换两个变量的值

let a = 1,
b = 2; [a, b] = [b, a]; console.log(a); // 2
console.log(b); // 1

默认值

当指定位置的属性不存在或其值为 undefined 时才会使用默认值。

let colors = [ "red" ];
let [ firstColor, secondColor = "green" ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"

嵌套数组解构

与嵌套对象解构的语法类似。

let colors = [ "red", [ "green", "lightgreen" ], "blue" ];
let [ firstColor, [ secondColor ] ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"

不定元素

通过 ... 语法将数组中的其余元素赋值给一个特定的变量。

let colors = [ "red", "green", "blue" ];
let [ firstColor, ...restColors ] = colors;
console.log(firstColor); // "red"
console.log(restColors.length); // 2
console.log(restColors[0]); // "green"
console.log(restColors[1]); // "blue"

可以通过不定元素实现数组赋值的功能(也可以通过concat方法实现)

let colors = [ "red", "green", "blue" ];
let [ ...clonedColors ] = colors;
console.log(clonedColors); // ["red", "green", "blue"]

Note

在被解构的数组中,不定元素必须为最后一个条目,在后面继续添加逗号会导致程序抛出语法错误。

混合解构

let node = {
type: "Identifier",
name: "foo",
loc: {
start: {
line: 1,
column: 1
},
end: {
line: 1,
column: 4
}
},
range: [0, 3]
}; let {
loc: { start },
range: [ startIndex ]
} = node; console.log(start.line); // 1
console.log(start.column); // 1
console.log(startIndex); // 0

解构参数

function setCookie(name, value, { secure, path, domain, expires }) {

}

setCookie("type", "js", {
secure: true,
expires: 60000
});

第三个参数传入的是对象,方法参数使用参数解构自动提供属性值到对应的参数。

Note

解构参数支持上面所有的解构特性。

必须传值的解构参数

第三个参数不传或者为null、undefined时,解析会出错。

需要为其提供默认值来解决这个问题。

function setCookie(name, value, { secure, path, domain, expires } = { }) {

}

解构参数的默认值

为解构参数中的某个或全部参数指定默认值

const setCookieDefaults = {
secure: false,
path: "/",
domain: "liujiajia.me",
expires: new Date(Date.now() + 360000000)
} function setCookie(name, value, {
secure = setCookieDefaults.secure,
path = setCookieDefaults.path,
domain = setCookieDefaults.domain,
expires = setCookieDefaults.expires
} = setCookieDefaults) {
// ...
}

【读书笔记】【深入理解ES6】#5-解构:使数据访问更便捷的更多相关文章

  1. 深入理解ES6之解构

    变量赋值的痛 对象 let o = {a:23,b:34}; let a = o.a; let b = o.b; 如上文代码,我们经常会遇到在各种场合需要获取对象中的值的场景,舒服一点的是获取单个属性 ...

  2. 进军es6(2)---解构赋值

    本该两周之前就该总结的,但最近一直在忙校招实习的事,耽误了很久.目前依然在等待阿里HR面后的结果中...但愿好事多磨!在阿里的某轮面试中面试官问到了es6的掌握情况,说明es6真的是大势所趋,我们更需 ...

  3. ES6 的解构赋值前每次都创建一个对象吗?会加重 GC 的负担吗?

    本文来源于知乎上的一个提问. 为了程序的易读性,我们会使用 ES6 的解构赋值: function f({a,b}){} f({a:1,b:2}); 这个例子的函数调用中,会真的产生一个对象吗?如果会 ...

  4. ES6 对象解构

    ES6 对象解构 第一眼看到,什么鬼? const { body } = document `` 其实等于: const body = document.body ``` http://es6.rua ...

  5. es6的解构赋值学习(1)

    相对es5的简单的"="赋值来说,es6增加了一种新的赋值模式--解构赋值,按照它的规则,可以从数组和对象中提取值来对变量进行赋值,个人觉得方便了很多,但是这个模式有点恶心人,相比 ...

  6. Es6 新增解构赋值

    1.数组的解构赋值 基本用法 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 要想实现解构,就必须是容器,或者具有可遍历的接口. 以前,为 ...

  7. ES6 之 解构赋值

    本博文配合 阮一峰 <ES6 标准入门(第3版)>一书进行简要概述 ES6 中变量的解构赋值. 数组的解构赋值 基本用法 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这 ...

  8. ES6之解构赋值

    截止到ES6,共有6种声明变量的方法,分别是var .function以及新增的let.const.import和class: 我们通常的赋值方法是: var foo='foo'; function ...

  9. ES6多层解构

    const info = { person: { name: 'xiaobe', other: { age: 22, } }, song: 'rolling', } // 解构person的内容 co ...

随机推荐

  1. 对于是否在一个python程序中编写函数的启发

    那我们到底是应该直接使用这些模块级别的函数呢,还是先编译一个模式对象,再调用模式对象的方法呢?这其实取决于正则表达式的使用频率,如果说我们这个程序只是偶尔使用到正则表达式,那么全局函数是比较方便的:如 ...

  2. JAVA入门[8]-测试mybatis

    上一节通过mybatis-generator自动生成了CategoryMapper接口,pojo等类,接下来我们写几个简单的测试来进行调用. 一.添加依赖 <dependency> < ...

  3. Java项目中使用Redis缓存案例

    缓存的目的是为了提高系统的性能,缓存中的数据主要有两种: 1.热点数据.我们将经常访问到的数据放在缓存中,降低数据库I/O,同时因为缓存的数据的高速查询,加快整个系统的响应速度,也在一定程度上提高并发 ...

  4. 自学Zabbix3.8.1.1-可视化Visualisation-Graphs简单图表

    自学Zabbix3.8.1.1-可视化Visualisation-Graphs简单图表 Zabbix提供了一些简单的图表,用于可视化由项目收集的数据. 用户不需要进行配置工作来查看简单的图表.他们是由 ...

  5. Python笔记·第九章—— 函数 (一)

    一.函数的作用 函数可以让我们代码结构更清晰,而且避免了代码的重复,冗余,使一段代码或者功能可以反复的被调用,大大提高了开发效率 二.函数的定义 def 函数名(参数1,参数2,*args,默认参数, ...

  6. 字符设备 Vs. 块设备 Character Device Vs. Block Device

    字符设备是指驱动发送/接受单个字符(例如字节)的设备. 块设备是指驱动发送/接受整块数据(例如512个字节为一个块)的设备. 常见的字符设备:串口,并口,声卡. 常见的块设备:硬盘(最小读取单位为扇区 ...

  7. 工作随笔——Golang interface 转换成其他类型

    新的公司,新的氛围.一年了,打算写点什么.so,那就写google的golang语言吧. 最最最基础的语法结构见go语言菜鸟教程 接下来写点菜鸟教程没有的. go语言的设计者认为:go语言必须让程序员 ...

  8. sourceTree每次拉取代码和提交代码都需要输入密码

    今天新安装的sourceTree导入项目,拉取代码的时候一直提示让我输入git密码,每次拉取和提交的时候都需要重新输入密码,甚是麻烦,在网上,搜索,解决办法五花八门,这里提供一种简单有效的方法供大家参 ...

  9. 'boost/iterator/iterator_adaptor.hpp' file not found之xcode生成时报错的解决方案

    xcode生成rn(0.49.3)项目的时候出现“'boost/iterator/iterator_adaptor.hpp' file not found之xcode”报错. 原因: /Users/x ...

  10. class_copyIvarList方法获取实例变量问题引发的思考

    在runtime.h中,你可以通过其中的一个方法来获取实例变量,那就是class_copyIvarList方法,具体的实现如下: - (NSArray *)ivarArray:(Class)cls { ...