【问题标题】:Object destructuring assignment with default value of itself具有自身默认值的对象解构赋值
【发布时间】:2021-02-04 02:09:20
【问题描述】:

我需要销毁一些变量可能已经有值的对象。

let foo = 1, bar, baz = 'Hello';

const config = { foo: 42 };

({ foo, bar, baz } = config);

console.log({ foo, bar, baz });

这给了我

{
  "foo": 42,
  "bar": undefined,
  "baz": undefined
}

但我真正想要的是

{
  "foo": 42,
  "bar": undefined,
  "baz": "Hello"
}

如果config中有同名的值,我想重写该值,如果没有,就改用原来的值。

我无法在解构时分配默认值,因为这些值是之前分配的。

({ foo = 1, bar, baz = 'Hello' } = config);

我知道我可以这样分配它,但它太笨重了,因为有超过 20 个变量。

({ foo = foo, bar = bar, baz = baz } = config);

有没有更好的方法来编写它而无需一直重复x = x

【问题讨论】:

  • 你有这么多独立变量的事实是一种气味。因为听起来它们都非常相关 - 它们可能存在于config - 如果我是你,请考虑是否可以将它们合并到一个对象中,它会让你的代码更加干燥(至少在本节中)。一旦构建了最终对象,如果需要,然后稍后再进行解构,IMO
  • @CertainPerformance 我试图这样做,但很难在不破坏任何东西的情况下进行重构,因为这些值无处不在,所以我最终放弃了。但我完全同意你的看法,这样会适得其反。

标签: javascript ecmascript-6 object-destructuring


【解决方案1】:

使用原始值(默认值)创建一个对象,并将config 传播到其中,覆盖默认值,然后对其进行解构:

let foo = 1, bar, baz = 'Hello';

const config = { foo: 42 };

({ foo, bar, baz } = { foo, bar, baz, ...config });

console.log({ foo, bar, baz });

【讨论】:

    【解决方案2】:

    Object.assign 将是解决您问题的理想人选。祝你好运^^!

    let foo = 1, bar, baz = 'Hello';
    
    const config = { foo: 42 };
    const target = {foo, bar, baz};
    const source = ({ foo, host, bar } = config);
    
    const result = Object.assign(target, source);
    console.log(result);

    如果您想重新分配变量而不是返回新对象,您可以执行以下操作。

    let foo = 1, bar, baz = 'Hello';
    const config = { foo: 42 };
    
    // Step 1: merge 2 objects
    const mergedObject = { foo, bar, baz, ...config };
    
    // Step 2: re-assign variables from `mergedObject`
    ({foo, bar, baz} = mergedObject);
    
    console.log({foo, bar, baz});

    【讨论】:

    • @Hao Wu 我刚刚用using spread更新了我的答案,请看一下^^!
    • 但是我想要的是重写变量而不是创建一个对象......如果你在它之后控制台日志foo,它仍然保持不变。
    • @HaoWu 哎呀,我误会了。我刚刚更新了我的答案。请再看一遍:)
    【解决方案3】:

    你可以循环config然后像这样赋值。

    let foo = 1, bar, baz = 'Hello';
    const config = { foo: 42 };
    const result = {foo, bar, baz};
    
    Object.entries(config).forEach(([key, value]) => {
      if(result[key])
        result[key] = value;
    });
    
    console.log(result);

    【讨论】:

    • console.log({ foo, bar, baz, ...config });一样只有一行^^!
    • 我需要更改foobarbaz定义的变量let,这只会改变result对象的属性:(
    猜你喜欢
    • 2018-08-20
    • 2016-10-30
    • 2017-07-12
    • 2019-09-30
    • 1970-01-01
    • 2012-07-11
    • 1970-01-01
    • 2020-10-15
    • 1970-01-01
    相关资源
    最近更新 更多