34.解构

原文: http://exploringjs.com/impatient-js/ch_destructuring.html

34.1。第一次尝试解构

通过正常分配,您可以一次提取一个数据。例如,通过:

通过解构,您可以通过接收数据的位置中的模式同时提取多个数据。前一代码中=的左侧是一个这样的位置。在以下代码中,行 A 中的方括号是解构模式。它提取索引 0 和索引 1 处的 Array 元素的值:

请注意,模式比数据“小”:我们只提取我们需要的东西。

34.2。构造与提取

为了理解解构是什么,请考虑 JavaScript 有两种相反的操作:

  • 您可以构建复合数据,例如通过设置属性和通过对象字面值。
  • 您可以从复合数据中提取数据,例如通过获取属性。

构建数据如下:

提取数据如下:

到目前为止,我们还没有看到提取多个值的方法。 解构 允许我们通过 解构模式 来做到这一点。在语法上,这样的模式看起来类似于多值构造,但是它们出现在接收数据的地方(例如,在分配的左侧),而不是在创建数据的地方(例如,在分配的右侧)。

A 行中的const声明并初始化了两个变量f2f1

34.3。我们在哪里可以破坏?

解构模式可用于“分配位置”,例如:

  • 变量声明:

  • 作业:

  • 参数定义:

请注意,变量声明包括for-of循环中的constlet声明:

接下来,我们将深入研究两种解构:对象解构和数组解构。

34.4。对象解构

对象解构 允许您通过看起来像对象字面值的模式批量提取属性值:

您可以将模式视为放置在数据上的透明工作表:模式键'street'在数据中具有匹配项。因此,数据值'Evergreen Terrace'被分配给模式变量s

您还可以对象解构原始值:

你可以对象构造数组(请记住,数组索引也是属性):

34.4.1。财产值缩写

对象字面值支持属性值缩写,对象模式也是如此:

34.4.2。休息属性

在对象字面值中,您可以具有传播属性。在对象模式中,您可以拥有 rest 属性(必须具有最后的属性):

rest 属性变量(例如remaining(行 A))被赋予一个对象,该对象具有其模式中未提及其键的所有数据属性。

34.4.3。语法陷阱:通过对象解构分配

如果我们在赋值中进行对象解构,我们就会遇到由语法歧义引起的陷阱 - 你不能用大括号开始一个语句,因为那时 JavaScript 认为你正在启动一个块:

34.解构 - 图1 为什么eval()

我们需要通过 eval()延迟解析,否则我们在解析此代码时会遇到异常。 assert.throws()仅在其函数体内抛出异常时才有效。

解决方法是将整个作业放在括号中:

34.解构 - 图2 练习:对象解构

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()的结果:

当我们使用属性键时,我们提到elementindex的顺序无关紧要:

如果我们只对两个结果中的一个感兴趣,那么解构也会很好地为我们服务:

所有这些便利性相结合,使得处理多个返回值的这种方式非常通用。

34.7。没找到匹配

如果模式的某个部分不匹配会发生什么?如果你使用非批处理运算符会发生同样的事情:你得到undefined

34.7.1。对象解构和缺少属性

如果对象模式中的属性在右侧没有匹配,则得到undefined

34.7.2。数组解构和缺少元素

如果数组模式中的元素在右侧没有匹配,则得到undefined

34.8。哪些值无法破坏?

34.8.1。你不能对象解构undefinednull

如果要解构的值是undefinednull,则对象解构仅失败。也就是说,只要通过点运算符访问属性,它就会失败。

34.8.2。您不能使用 Array-destructure 非可迭代值

数组解构要求解构的值是可迭代的。因此,您不能使用 Array-destructure undefinednull。但是,您不能使用 Array-destructure 非可迭代对象:

34.解构 - 图3 测验:基本

参见测验应用程序

34.9。 (高级)

所有其余部分都是高级的。

34.10。默认值

通常,如果模式不匹配,则相应的变量设置为undefined

使用默认值,您可以指定undefined以外的值,在这种情况下应使用该值:

在 A 行中,我们将p的默认值指定为123。使用该默认值,因为我们正在解构的数据没有名为prop的属性。

34.10.1。 Array-destructuring 中的默认值

这里,我们有两个默认值分配给变量xy,因为相应的元素不存在于被解构的数组中。

Array 模式的第一个元素的默认值是1,第二个元素的默认值是2

34.10.2。对象解构中的默认值

您还可以为 object-destructuring 指定默认值:

在解构的对象中既不存在属性键first也不存在属性键last。因此,使用默认值。

使用属性值 shorthands,此代码变得更简单:

34.11。参数定义类似于解构

考虑到我们在本章中学到的内容,参数定义与数组模式(其余元素,默认值等)有很多共同之处。实际上,以下两个函数声明是等效的:

34.12。嵌套解构

到目前为止,我们只使用变量作为解构模式中的赋值目标。但您也可以使用模式作为赋值目标,这使您可以将模式嵌套到任意深度:

在 A 行的 Array 模式中,有一个嵌套的对象模式,索引为 1。

34.13。进一步阅读

34.解构 - 图4 测验:高级

参见测验应用程序