1.混合解构
对象与数组解构能被用在一起,以创建更复杂的解构表达式。在对象与数组混合而成的结构中,这么做能准确提取其中想要的信息片段。例如:
1 | let node = { |
此代码将 node.loc.start
与 node.range[0]
提取出来,并将它们的值分别存储到 start
与 startIndex
中。
注意,解构模式中的 loc:
与 range:
只是对应于 node
对象中属性的位置。混合使用对象与数组解构,node
的任何部分都能提取出来。
对于从 JSON 配置结构中抽取数据来说,这种方法尤其有用,因为它不需要探索整个解构。
2.参数解构
解构还有一个特别有用的场景,即在传递函数参数时。
当 JS 的函数接收大量可选参数时,一个常用模式是创建一个 options
对象,其中包含了附加的参数,例如:
1 | // options 上的属性表示附加参数 |
很多 JS 的库都包含了类似于此例的 setCookie()
函数。在此函数内,name
与 value
参数是必须的,而 secure
path
domain
与 expires
则不是。并且因为此处对于其余数据并没有顺序要求,将它们作为 options
对象的具名属性会更有效率,而无须列出一堆额外的具名参数。
这种方法很有用,但无法仅通过查看函数定义就判断出函数所期望的输入,你必须阅读函数体的代码。
参数解构提供了更清楚地表明函数期望输入的替代方案。它使用对象或数组解构的模式替代了具名参数。
下例是重写版本的 setCookie()
函数:
1 | function setCookie(name, value, { secure, path, domain, expires }) { |
此函数的行为类似上例,但此时第三个参数使用了解构来抽取必要的数据。现在对于 setCookie()
函数的使用者来说,解构参数之外的参数明显是必须的;而可选项目存在于额外的参数组中,这同样是非常明确的;同时,若使用了第三个参数,其中应当包含什么值当然也是及其明确的。
解构参数在没有传递值的情况下类似于常规参数,它们会被设为 undefined
。
2.1 解构的参数是必需的
参数解构有一个怪异点:默认情况下调用函数时未给参数解构传值会抛出错误。例如,用以下方式调用上例中的 setCookie()
函数就会报错:
1 | // 出错! |
调用时第三个参数缺失了,因此它不出预料地等于 undefined
。这导致了一个错误,因为参数解构实际上只是解构声明的简写。当 setCookie()
函数被调用时,JS 引擎实际上是这么做的:
1 | function setCookie(name, value, options) { |
既然在赋值右侧的值为 null
或 undefined
时,解构会抛出错误,那么未向 setCookie()
函数传递第三个参数就同样会出错。
若让解构的参数作为必选参数,那么上述行为并不会令人困扰。然而若要求它们是可选的,可以给解构的参数提供默认值来处理这种行为,例如:
1 | function setCookie(name, value, {secure, path, domain, expires} = {}) { |
此例为第三个参数提供了一个空对象作为其默认值。给解构的参数提供默认值,也就意味着若未向 setCookie()
函数传递第三个参数,则 secure
path
domain
与 expires
的值全都会是 undefined
,此时不会有错误被抛出。
2.2 参数解构的默认值
可以为参数解构提供可解构的默认值,就像在解构赋值时所做的那样,只需在其中每个参数后面添加等号并指定默认值即可。例如:
1 | function setCookie(name, value, |
此代码中参数解构给每个属性都提供了默认值,所以你可以避免检查指定属性是否已被传入(以便在未传入时使用正确的值)。而整个解构的参数同样有一个默认值,即一个空对象,令该参数成为可选参数。
这么做使得函数声明看起来比平时要复杂一些,但却是为了确保每个参数都有可用的值而付出的微小代价。