如何使用对象解构来处理嵌套的默认参数? [英] How to handle nested default parameters with object destructuring?
问题描述
我试图弄清楚是否可以通过解构来处理多个级别的默认参数。由于用文字解释并不容易,下面是一个循序渐进的例子......
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 $ c当你解构属性时,$ c>变量。如果您想为该属性引入一个
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屋!