34.解构
原文: http://exploringjs.com/impatient-js/ch_destructuring.html
34.1。第一次尝试解构
通过正常分配,您可以一次提取一个数据。例如,通过:
通过解构,您可以通过接收数据的位置中的模式同时提取多个数据。前一代码中=
的左侧是一个这样的位置。在以下代码中,行 A 中的方括号是解构模式。它提取索引 0 和索引 1 处的 Array 元素的值:
请注意,模式比数据“小”:我们只提取我们需要的东西。
34.2。构造与提取
为了理解解构是什么,请考虑 JavaScript 有两种相反的操作:
- 您可以构建复合数据,例如通过设置属性和通过对象字面值。
- 您可以从复合数据中提取数据,例如通过获取属性。
构建数据如下:
提取数据如下:
到目前为止,我们还没有看到提取多个值的方法。 解构 允许我们通过 解构模式 来做到这一点。在语法上,这样的模式看起来类似于多值构造,但是它们出现在接收数据的地方(例如,在分配的左侧),而不是在创建数据的地方(例如,在分配的右侧)。
A 行中的const
声明并初始化了两个变量f2
和f1
。
34.3。我们在哪里可以破坏?
解构模式可用于“分配位置”,例如:
变量声明:
作业:
参数定义:
请注意,变量声明包括for-of
循环中的const
和let
声明:
接下来,我们将深入研究两种解构:对象解构和数组解构。
34.4。对象解构
对象解构 允许您通过看起来像对象字面值的模式批量提取属性值:
您可以将模式视为放置在数据上的透明工作表:模式键'street'
在数据中具有匹配项。因此,数据值'Evergreen Terrace'
被分配给模式变量s
。
您还可以对象解构原始值:
你可以对象构造数组(请记住,数组索引也是属性):
34.4.1。财产值缩写
对象字面值支持属性值缩写,对象模式也是如此:
34.4.2。休息属性
在对象字面值中,您可以具有传播属性。在对象模式中,您可以拥有 rest 属性(必须具有最后的属性):
rest 属性变量(例如remaining
(行 A))被赋予一个对象,该对象具有其模式中未提及其键的所有数据属性。
34.4.3。语法陷阱:通过对象解构分配
如果我们在赋值中进行对象解构,我们就会遇到由语法歧义引起的陷阱 - 你不能用大括号开始一个语句,因为那时 JavaScript 认为你正在启动一个块:
为什么eval()
?
我们需要通过 eval()延迟解析,否则我们在解析此代码时会遇到异常。 assert.throws()
仅在其函数体内抛出异常时才有效。
解决方法是将整个作业放在括号中:
练习:对象解构
exercises/destructuring/object_destructuring_exrc.js
34.5。数组的解构
Array-destructuring 允许您通过看起来像 Array literals 的模式批量提取 Array 元素的值:
您可以通过提及 Array 模式中的孔来跳过元素:
A 行中 Array 模式的第一个元素是一个洞,这就是为什么忽略索引 0 处的 Array 元素。
当操作返回数组时,数组解构很有用。例如,正则表达式方法.exec()
:
您还可以使用解构来交换两个变量的值,而无需临时变量:
34.5.1。休息元素
在 Array 字面值中,您可以使用 spread 元素。在 Array 模式中,您可以拥有 rest 元素(必须最后):
诸如remaining
(行 A)之类的 rest 元素变量被赋予一个 Array,其中包含未提及的所有析构值的元素。
34.5.2。数组解构适用于任何可迭代的
Array-destructuring 可以应用于任何可迭代的值,而不仅仅是 Arrays:
34.6。解构用例:多个返回值
如果函数返回多个值(解包为 Array 或打包为对象),则解构非常有用。
考虑一个在数组中查找元素的函数findElement()
:它的参数是一个函数,它接收元素的值和索引,并返回一个布尔值,指示这是否是调用者正在寻找的元素。我们现在面临一个两难困境:findElement()
应该返回它找到的元素的值还是索引?一种解决方案是创建两个单独的函数,但这会导致重复的代码,因为两个函数都非常相似。
以下实现通过返回包含找到的元素的索引和值的对象来避免重复:
解构有助于我们处理findElement()
的结果:
当我们使用属性键时,我们提到element
和index
的顺序无关紧要:
如果我们只对两个结果中的一个感兴趣,那么解构也会很好地为我们服务:
所有这些便利性相结合,使得处理多个返回值的这种方式非常通用。
34.7。没找到匹配
如果模式的某个部分不匹配会发生什么?如果你使用非批处理运算符会发生同样的事情:你得到undefined
。
34.7.1。对象解构和缺少属性
如果对象模式中的属性在右侧没有匹配,则得到undefined
:
34.7.2。数组解构和缺少元素
如果数组模式中的元素在右侧没有匹配,则得到undefined
:
34.8。哪些值无法破坏?
34.8.1。你不能对象解构undefined
和null
如果要解构的值是undefined
或null
,则对象解构仅失败。也就是说,只要通过点运算符访问属性,它就会失败。
34.8.2。您不能使用 Array-destructure 非可迭代值
数组解构要求解构的值是可迭代的。因此,您不能使用 Array-destructure undefined
和null
。但是,您不能使用 Array-destructure 非可迭代对象:
测验:基本
参见测验应用程序。
34.9。 (高级)
所有其余部分都是高级的。
34.10。默认值
通常,如果模式不匹配,则相应的变量设置为undefined
:
使用默认值,您可以指定undefined
以外的值,在这种情况下应使用该值:
在 A 行中,我们将p
的默认值指定为123
。使用该默认值,因为我们正在解构的数据没有名为prop
的属性。
34.10.1。 Array-destructuring 中的默认值
这里,我们有两个默认值分配给变量x
和y
,因为相应的元素不存在于被解构的数组中。
Array 模式的第一个元素的默认值是1
,第二个元素的默认值是2
。
34.10.2。对象解构中的默认值
您还可以为 object-destructuring 指定默认值:
在解构的对象中既不存在属性键first
也不存在属性键last
。因此,使用默认值。
使用属性值 shorthands,此代码变得更简单:
34.11。参数定义类似于解构
考虑到我们在本章中学到的内容,参数定义与数组模式(其余元素,默认值等)有很多共同之处。实际上,以下两个函数声明是等效的:
34.12。嵌套解构
到目前为止,我们只使用变量作为解构模式中的赋值目标。但您也可以使用模式作为赋值目标,这使您可以将模式嵌套到任意深度:
在 A 行的 Array 模式中,有一个嵌套的对象模式,索引为 1。
34.13。进一步阅读
- “探索 ES6”进一步深入解构。
测验:高级
参见测验应用程序。