在Array.reduce中使用扩展表示法

Aks*_*til 4 javascript ecmascript-6 ecmascript-next

我试图让es6语法适用于此代码片段.

let checkList = [1, 2].map(i => "Check " + i)

let checks = checkList
  // .reduce((acc, check) => Object.assign(acc, {[check]: {valid: false}}), {})
  .reduce((acc, check) => {...acc, {[check]: {valid: false}}}, {})
console.log(checks)
Run Code Online (Sandbox Code Playgroud)

如果我在https://babeljs.io中使用注释行的输出如下所示,这是我想要使用新语法得到的.

Object {
  "Check 1": Object {
    "valid": false
  },
  "Check 2": Object {
    "valid": false
  }
}
Run Code Online (Sandbox Code Playgroud)

我不确定此代码中是否存在语法错误.我尝试选择babeljs中的所有预设,但它无法正确编译.

Est*_*ask 5

对象传播是第4阶段提案,不属于现有规范.应该在Babel中启用第3阶段预设,即transform-object-rest-spread.

上面的代码中存在语法错误,即使使用所需的预设也会阻止它正确编译.

应该是

let checks = checkList
  .reduce((acc, check) => ({...acc, [check]: {valid: false}}), {});
Run Code Online (Sandbox Code Playgroud)

  • 虽然这有效,但效率很低。在reduce()中使用展开运算符是O(n^2)而不是O(n)。https://prateeksurana.me/blog/why-using-object-spread-with-reduce-bad-idea/ (2认同)

Seb*_*xel 5

首先,您无需将属性包装在一个额外的对象中(除非您也想在该对象上使用散布运算符)。

所以{...acc, {[check]: {valid: false}}}可以成为{...acc, [check]: {valid: false}}

这意味着您要向累加器添加一个对象。该对象的键是您为其分配的名称(Check[n]),而值是您设置的名称({valid ...})。

其次,据我所知,如果没有显式的新值,就不能使用散布运算符。因此,您应该将状态写在新行上,例如:

let checks = checkList.reduce((acc, check) => {
  return {...acc, [check]: {valid: false}}
}, {})
Run Code Online (Sandbox Code Playgroud)

或用多余的括号括起来:

let checks = checkList.reduce((acc, check) => ({...acc, [check]: {valid: false}}) , {})
Run Code Online (Sandbox Code Playgroud)