如何使用对象解构来处理嵌套的默认参数? [英] How to handle nested default parameters with object destructuring?

查看:287
本文介绍了如何使用对象解构来处理嵌套的默认参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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




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



解构此对象很简单:

  let obj = {
foo:'Foo',
bar:'Bar'
};

使用 {foo ='Foo',bar ='Bar'} = {} 在函数签名中,如果在调用函数时没有参数传递,则会创建一个对象。如果一个对象被传递,但是一些被引用的属性是 undefined ,它们将被它们的默认值替换。这段代码工作的很好:

function fn1({foo ='Foo', bar ='Bar'} = {}){console.log(foo,bar);} // OKfn1(); // Foo Barfn1({foo:'Quux'}); // Quux Barfn1({bar:'Quux'}); // Foo Quuxfn1({foo:'Quux',bar:'Quux'}); // Quux Quux



2 - 嵌套对象解构,

解构这个对象更难:

  let obj = {
foo:'Foo',
bar:{
quux:'Quux',
corge:'Corge'
}
};

{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);} // OKfn2(); // Foo Quux Corgefn2({foo:'Quux'}); // Quux Quux Corge //糟糕!fn2({bar:{quux:'Baz'}}); // Foo Baz undefinedfn2({foo:'Quux',bar:{corge:'Baz'}}); // Quux undefined Baz  



3 - 深度默认嵌套对象解构参数



我想在对象层次的所有级别设置默认参数,以使用某种级联解构。我试过了,但它不起作用:



function fn3({foo ='Foo',bar =({quux ='Quux',corge ='Corge'} = {})} = {}){console.log(foo,bar.quux,bar.corge);} //哎呀!FN3(); // Foo undefined undefinedfn3({foo:'Quux'}); // Quux undefined undefinedfn3({bar:{quux:'Baz'}}); // Foo Baz undefinedfn3({foo:'Quux',bar:{corge:'Baz'}}); // Quux undefined Baz






你知道ES6中是否允许这样的功能。如果是,我该如何实现它?

解决方案

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

  {...,propertyName:target = defaultInitialiser,...} 

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

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

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

请注意,没有 bar 变量。如果您想为该属性引入一个 bar 变量,您可以重复属性名称并执行

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


I am trying to figure out if it is possible to handle multiple levels of default parameters with destructuring. Since it is not easy to explain with words, here is a step-by-step example...


1 - Flat object destructuring with default parameters

Destructuring this object is easy:

let obj = {
  foo: 'Foo',
  bar: 'Bar'
};

With {foo = 'Foo', bar = 'Bar'} = {} in a function signature, an object will be created if there is no argument passed when the function is called. If an object is passed but some referenced properties are undefined, they will be replaced by their default values. This code works fine:

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

2 - Nested object destructuring with shallow default parameters

Destructuring this object is harder:

let obj = {
  foo: 'Foo',
  bar: {
    quux: 'Quux',
    corge: 'Corge'
  }
};

{foo = 'Foo', bar = 'Bar'} = {} is not a viable option anymore, but now we can use {foo = 'Foo', bar = {quux: 'Quux', corge: 'Corge'}} = {} in a function signature. Again, if no argument is given when the function is called, an object is created and the core properties (foo and bar) are extracted. If an object is passed, only undefined properties (foo or bar) will be destructured with their default values.

The problem is that the object properties of bar (quux and corge) are not part of the "top-level destructuring". This means quux or corge will be undefined if they are not explicitly set when bar is passed as an argument:

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

3 - Nested object destructuring with deep default parameters

I would like to set default parameters at all levels of the object hierarchy to use a sort of "cascading destructuring". I tried this, but it does not work:

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


Do you know if such a feature is allowed in ES6. If yes, how can I implement it?

解决方案

The generic pattern for destructuring object properties is

{ … , propertyName: target = defaultInitialiser, … }

(when the property name is exactly the same as the target variable identifier we can join them).

But target is not only for variables, it can be any assignment target - including nested destructuring expressions. So for your case (3) you want to use exactly the same approach as with (1) on the top level of the parameter - default initialise the property with an empty object and destructure its parts:

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

Notice that there is no bar variable when you destructure that property. If you want to introduce a bar variable for the property as well, you could repeat the property name and do

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

这篇关于如何使用对象解构来处理嵌套的默认参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆