如何使用对象解构处理嵌套的默认参数?

Bad*_*bra 9 javascript function destructuring default-parameters ecmascript-6

我试图弄清楚是否有可能通过解构处理多个级别的默认参数.由于用文字解释起来并不容易,这是一个循序渐进的例子......


1 - 使用默认参数进行扁平对象解构

解构这个对象很简单:

let obj = {
  foo: 'Foo',
  bar: 'Bar'
};
Run Code Online (Sandbox Code Playgroud)

随着{foo = 'Foo', bar = 'Bar'} = {}在函数签名,如果没有当函数被调用时传入的参数的对象将被创建.如果传递了一个对象但是引用了一些属性undefined,则它们将被默认值替换.这段代码工作正常:

function fn1({foo = 'Foo', bar = 'Bar'} = {}) {
  console.log(foo, bar);
}

// OK
fn1(); // Foo Bar
fn1({foo: 'Quux'}); // Quux Bar
fn1({bar: 'Quux'}); // Foo Quux
fn1({foo: 'Quux', bar: 'Quux'}); // Quux Quux
Run Code Online (Sandbox Code Playgroud)

2 - 使用浅默认参数的嵌套对象解构

解构这个对象更难:

let obj = {
  foo: 'Foo',
  bar: {
    quux: 'Quux',
    corge: 'Corge'
  }
};
Run Code Online (Sandbox Code Playgroud)

{foo = 'Foo', bar = 'Bar'} = {}不再是一个可行的选择,但现在我们可以{foo = 'Foo', bar = {quux: 'Quux', corge: 'Corge'}} = {}在函数签名中使用.同样,如果在调用函数时没有给出参数,则创建一个对象foo并bar提取核心属性(和).如果传递了一个对象,则只有未定义的属性(foo或bar)将使用其默认值进行解构.

问题是bar(quux和corge)的对象属性不是"顶级解构"的一部分.这意味着quux或corge将是undefined在bar作为参数传递时未明确设置的:

function fn2({foo = 'Foo', bar = {quux: 'Quux', corge: 'Corge'}} = {}) {
  console.log(foo, bar.quux, bar.corge);
}

// OK
fn2(); // Foo Quux Corge
fn2({foo: 'Quux'}); // Quux Quux Corge

// Oops!
fn2({bar: {quux: 'Baz'}}); // Foo Baz undefined
fn2({foo: 'Quux', bar: {corge: 'Baz'}}); // Quux undefined Baz
Run Code Online (Sandbox Code Playgroud)

3 - 使用深度默认参数进行嵌套对象解构

我想在对象层次结构的所有级别设置默认参数,以使用一种"级联解构".我试过这个,但它不起作用:

function fn3({foo = 'Foo', bar = ({quux = 'Quux', corge = 'Corge'} = {})} = {}) {
  console.log(foo, bar.quux, bar.corge);
}

// Oops!
fn3(); // Foo undefined undefined
fn3({foo: 'Quux'}); // Quux undefined undefined
fn3({bar: {quux: 'Baz'}}); // Foo Baz undefined
fn3({foo: 'Quux', bar: {corge: 'Baz'}}); // Quux undefined Baz
Run Code Online (Sandbox Code Playgroud)


你知道ES6中是否允许这样的功能吗?如果是,我该如何实施呢?

Ber*_*rgi 7

解构对象属性的通用模式是

{ … , propertyName: target = defaultInitialiser, … }
Run Code Online (Sandbox Code Playgroud)

(当属性名称与目标变量标识符完全相同时,我们可以加入它们).

但target不仅仅是变量,它可以是任何赋值目标 - 包括嵌套的解构表达式.因此,对于您的情况(3),您希望在参数的顶层使用与(1)完全相同的方法 - 默认使用空对象初始化该属性并对其部分进行解构:

function fn3({foo = 'Foo', bar: {quux = 'Quux', corge = 'Corge'} = {}} = {}) {
  console.log(foo, quux, corge);
}
Run Code Online (Sandbox Code Playgroud)

请注意,bar在解构该属性时没有变量.如果你想bar为属性引入一个变量,你可以重复属性名称并执行

function fn3({foo = 'Foo', bar, bar: {quux = 'Quux', corge = 'Corge'} = {}} = {}) {
  console.log(foo, bar, quux, corge);
}
Run Code Online (Sandbox Code Playgroud)