ES6命名对象参数解构

8

我目前正在使用对象解构模式与默认参数,该答案中描述了 ES6 对象解构默认参数

(function test({a = "foo", b = "bar"} = {}) {
  console.log(a + " " + b);
})();

我希望能够在函数体中直接访问对象参数,而不必将其分配给变量并显式列出每个键。

(function test({a = "foo", b = "bar"} = {}) {
  const options = {a, b};
  console.log(options);
})();

我尝试给对象参数命名,但是函数失去了将缺失的键解析为默认值的能力。

(function test(options = {a = "foo", b = "bar"} = {}) {
  console.log(options);
})();

当解构为命名参数时,似乎忽略了默认参数。

这是ES6规范的一部分吗?有没有办法在函数体中不需要额外的代码来实现所需的行为?


编辑: 我删除了一个多余的例子,它并没有为问题增添上下文。


默认参数适用于解构变量。如果您想将它们保留为对象属性,则需要在函数体内执行此操作 - 正如答案所解释的那样。 - Estus Flask
@estus,你有这个信息的来源吗?这是关于ES6规范的技术问题,不是一般的编程实践。 - Jared Deckard
没有源代码,这是从ES6解构的功能中得出的结论。你想要做的事情不能仅通过函数签名来处理,应该在函数体中完成。另外,在第二个片段中明确重构本身并不是坏事。它允许从对象中排除无效的键。 - Estus Flask
你的第三个代码片段的作用类似于 function test(options = ({a = "foo", b = "bar"} = {})) - 这不是你想要的。 - Bergi
@Bergi 那很有道理。如果你把它发表为答案,我会选择它。 - Jared Deckard
值得注意的是,这段代码在Firefox中会出错。看起来我的困惑可能只是由于V8的实现允许未定义的行为所导致的。 - Jared Deckard
1个回答

6
说实话,我认为你过于复杂化了。默认参数并非强制要求——在这种情况下,如果不使用默认参数,你的代码可以更简洁。
我会直接将对象options作为参数,并在函数体内进行解构赋值,同时指定默认值。

function test(options) {
    options = Object.assign({a: 'foo', b: 'bar'}, options);
    let {a, b} = options;
    console.log(options, a, b);
}

test(); // foo bar
test({a: 'baz'}); // baz bar
test({b: 'fuz'}); // foo fuz
test({c: 'fiz'}); // foo bar

关于你最后的代码片段,特别需要注意的是:

(function test(options = {a: "foo", b: "bar"}) {
  console.log(options);
})({a: "baz"});

问题在于当传递的值为undefined时,会使用默认参数。这里传递的值是{a: "baz"},不是undefined,因此会忽略默认参数。对象不会自动合并。
更广泛地回答您的问题:在方法参数中,没有办法同时获取一个对象和解构它的一些属性。坦白地说,函数签名已经足够难以一眼读懂了。

1
我很感谢你的实用回答,但我更感兴趣的是为什么我提到的语法是有效的,但产生了意外的结果。 - Jared Deckard
@JaredDeckard 如果是这样,也许你可以把你的问题具体化一点。我不确定你觉得哪些结果是意外的。 - lonesomeday
我尝试给对象参数命名,但函数失去了将缺失的键解析为默认值的能力。...这是ES6规范的一部分吗?有没有办法在函数体中不添加额外代码实现所需的行为?我不是在询问实现此功能的最实用方法,而是在询问ES6规范,正如结尾问题所示。 - Jared Deckard
1
编辑:我删除了多余的 options = {a: "foo", b: "bar"} 示例,因为它没有为问题添加上下文。options = {a = "foo", b = "bar"} = {} 是有效的,但结果不符合预期。我想知道这是否是 ES6 的预期行为。 - Jared Deckard
最好使用ES6的 Object.assign: options = { a: 'foo', b: 'bar', ...options }; - Mingwei Samuel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接