首页 \ 问答 \ 如何使用对象解构处理嵌套的默认参数?(How to handle nested default parameters with object destructuring?)

如何使用对象解构处理嵌套的默认参数?(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);
}

// OK
fn1(); // Foo Bar
fn1({foo: 'Quux'}); // Quux Bar
fn1({bar: 'Quux'}); // Foo Quux
fn1({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 = 'Foo', bar = {quux: 'Quux', corge: 'Corge'}} = {} 。 同样,如果在调用函数时没有给出参数,则会创建一个对象并提取核心属性( foobar )。 如果传递了一个对象,则只有未定义的属性( foobar )将使用其默认值进行解构。

问题是barquuxcorge )的对象属性不是“顶级解构”的一部分。 这意味着如果在将bar作为参数传递时未明确设置,则quuxcorge将是undefined的:

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 - 使用深度默认参数进行嵌套对象解构

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

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


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


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?


原文:https://stackoverflow.com/questions/43901734
更新时间:2020-02-19 04:43

最满意答案

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

{ … , propertyName: target = defaultInitialiser, … }

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

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

function 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);
}

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);
}
2017-05-11

相关问答

更多

对象解构:如何使用中间嵌套属性(object destructuring: how to use intermediate nested property)

我能想到的最接近的是: var { iWantThis, iWantThis: { andThis, andThisToo } } = x; 我以为我会使用let ,如果我使用的是ES6;) The closest I can come up with is: var { iWantThis, iWantThis: { andThis, andThisToo } } = x; Thought I'd use let instead, if I'm using ES6 ;)

JS嵌套对象中的解构对象(Destructuring Object in JS - Nested Object)

你能用这个吗? const {user} = xhrResponse.person || {}; 对于更新的用例,我想知道这是否可行? $q.all([ somePromise, someOtherPromise, getPersonPromise.then(res => (res.person || {}).user) ]).then(promises => [vm.promise1, vm.promise2, vm.user] = promises); Could you ju ...

将嵌套对象解构为函数参数(Destructuring nested objects as function parameters)

你可以这样做: const myFunc = ({event: {target: {name}}}) => { console.log(name) } myFunc({event: {target: {name: 'fred'}}}) .as-console-wrapper { max-height: 100% !important; top: 0; } 这是另一个实现,两个参数都有,但第二个完全是optionnal: const myFunc = ( {name: n ...

嵌套参数解构与默认值(nested parameter destructuring with default values)

您的代码不遵循对象解构语法,如此处所示,请检查: function getProducts({query, pagination: {offset, limit, sort}} = {query: {},pagination: {offset: 0, limit: 25, sort: {_id: 1}}}){ console.log(query, offset, limit, sort); } getProducts() getProducts({query: {}, pagi ...

使用嵌套对象和默认值进行解构(Destructuring with nested objects and default values)

只需用=替换= : const {a, b, c: {e = 'default', f = 'default'}} = require('./something') 演示: const { a, b, c: { e = 'default', f = 'default'} } = {a: 1, b: 2, c: {e: 3}} console.log(`a: ${a}, b: ${b}, e: ${e}, f: ${f}`) 它打印: a: 1, b: 2, e: 3, f: default ...

嵌套对象解构[重复](Nested Object destructuring [duplicate])

const { user: { name: { first: firstName = 'firstName', last: lastName = 'lastName' } = {} } = {} } = data const { user: { name: { first: firstName = 'firstName', last: lastName = 'lastName' } = {} } = {} } = data

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

用于解构对象属性的通用模式是 { … , propertyName: target = defaultInitialiser, … } (当属性名称与目标变量标识符完全相同时,我们可以加入它们)。 但target不仅仅是变量,它可以是任何赋值目标 - 包括嵌套的解构表达式。 因此,对于您的情况(3),您希望在参数的顶层使用与(1)完全相同的方法 - 默认使用空对象初始化属性并对其部分进行解构: function fn3({foo = 'Foo', bar: {quux = 'Quux', cor ...

在解构参数中键入默认参数(Typed default arguments in destructuring parameters)

type Formatter = { (n: number): (number | string) }; function example2({ bar = -1, transform = Math.abs as Formatter } = {}) { // ERROR: cannot find name 'transform' return transform(bar) + ' is the value'; } 使用默认参数时,您的目标是进行类型推断。 如果 ...

在对象解构中使用默认值,同时保留任何未默认的值(Using default values in object destructuring while retaining any un-defaulted values)

您不能使用当前的es6,但可以使用第2阶段预设的休息操作员。 function f({speed= 0, location: 'home', ...others}) { return Object.assign({}, {speed, location}, others); } You can't with current es6 but you can using rest operator available on via stage 2 preset. function f({spe ...

对象分配的嵌套解构(Nested Destructuring on Object Assignments)

对于嵌套级别,您可以重复相同的语法,如同对顶级进行解构: 根据您的评论编辑 我需要数组中的对象 let node = { ItemTitle: 'Title', ItemId: 5, Menu: {Item: [{ItemId: 579}]} } let { ItemId: id, // extract `node.ItemId` into a variable called `id` ItemTitle: title, // extract `n ...

相关文章

更多

最新问答

更多
  • 如何保护Solr只允许SELECT请求给用户并禁止其他任何东西?(How to secure Solr to allow SELECT request to only users and disallow anything else?)
  • XPath表达式无效/错误TFHpple SWIFT 1.2(XPath Expression not working/incorrect TFHpple SWIFT 1.2)
  • css3 3D变换不能平滑地制作动画(css3 3D transform doesn't animate smoothly)
  • 运行时错误'91'和Outlook.Application = <对象变量或没有设置块变量>?(Run-time error '91' & Outlook.Application = Object variable or With block variable not set?)
  • 慢的webservice问题(Slow webservice problem)
  • textview的不正确对齐方式(Improper alignment of a textview)
  • 在第一步“Hello World”中出现Java错误(Cannot run “Hello World” program in Eclipse)
  • 为什么十六进制地址是14个字符?(why the hex address is 14 character?)
  • 如何在Python中的不同类中使用变量?(How to use variable in different classes in Python?)
  • asp:GridView HYPERLINKFIELD - datanavigateurlformatstring中的asp代码(asp:GridView HYPERLINKFIELD - asp code inside datanavigateurlformatstring)
  • 关于adaboost算法(About adaboost algorithm)
  • 在Matlab上内置图像(Built in Images on Matlab)
  • java swing:输入键事件时焦点丢失(java swing: Focus lost on enter key event)
  • C#中的通用约束,T是相同的TSomethingElse,对吧?(Generic constraints in C#, T is the same TSomethingElse, right?)
  • 从mybatis中的光标获取数据(Fetching data from cursor in mybatis)
  • 在运行时从XML构建对象的最佳方法(Best way for building objects out of XMLs at runtime)
  • 在整个窗口中拉伸sf :: Sprite(Stretch sf::Sprite across entire window)
  • Selenium Node API Web驱动程序等待超时处理程序(Selenium Node API web driver wait timeout handler)
  • 函数使用并且是map的一部分(循环依赖?)(Function uses and is part of map (circular dependency?))
  • 是否可以在C ++ 14中使用可选模板参数创建类型元组?(Is possible to make a tuple of types with optional template parameters in C++14?)
  • PHP从窗帘后面打印/ f(PHP prints /f from behind the curtains)
  • JFrame的contentPane的LayoutManager(LayoutManager of JFrame's contentPane)
  • 用于Instagram Feed的图像滚动(Image Roll Overs for Instagram Feed)
  • 如何显示拉伸字体(双倍宽度/高度)?(How to display stretched font (double width/height)?)
  • 文件操作API在fileapi.h和stdio.h中的WP8差异?(WP8 differences between file manipulation APIs in fileapi.h and stdio.h?)
  • 保存失败后Rails没有回滚事务()(Rails not rolling back transaction after failed save())
  • jqgrid中的分页问题与数组数据(Pagination problem in jqgrid with array data)
  • 重定向时,通过其他页面上的URL调用javascript函数(Call javascript function through url on otherpage while Redirecting)
  • 如何使用InvokeCommandAction调用我的方法并传入参数?(How do I go about using InvokeCommandAction to call a method of mine and pass in parameters?)
  • Jquerymobile按钮仅显示页面的第一个外观(Jquerymobile buttons are shown only first apperance of the page)