对象解构为另一个对象不起作用

Object destructuring into another object does not work

今天我不得不合并两个对象,选择一个对象的属性 a 并将它们放在一个对象 b 中。我不明白为什么第一个 syntax/statement 不工作,而第二个是。

let user = { a: 1, b: 2 };
let data = { z: 1, c: 3, f: 8, d: 4 };

// Let's say I want user to be { a: 1, b: 2, c: 3}

// method 1 (not works) 
const r1 = {
    ...user,
    ...({c} = data)
};
document.getElementById("r1").innerText = JSON.stringify(r1);

// method 2 (works)
const r2 = {
    ...user,
    ...(({c}) => ({c}))(data)
};
document.getElementById("r2").innerText = JSON.stringify(r2);

您可以在 https://jsfiddle.net/Ljb7ndp4/6/

上试用代码

在第二种方法中,您将创建一个 IIFE(立即调用的函数表达式)。

来自 MDN docs、"an IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined"。方法 2 上的 IIFE 返回一个像 {c: <value>} 这样的对象。由于对象支持扩展运算符,您可以在对象定义中使用它。

要在您的代码中将其可视化,您可以将 IIFE 的结果分配给一个变量并在控制台上打印结果。

const val = (({c}) => ({c}))(data)
console.log(val) // { c: 3 }

箭头函数语法,在这种情况下,有点难以想象正在发生的事情,但是代码:

(({c}) => ({c}))(data);

是这个的简短版本,在我看来更易读。

(function(arg) {
  return { c: arg.c }
})(data);

因此,我们可以将其转换为箭头函数以逐步了解所有转换。

最初我们可以将函数转换为使用箭头函数语法:

((arg) => {
  return { c: arg: c }
})(data)

然后我们可以从收到的参数中解构c

(({c}) => {
  return { c: c }
})(data)

由于创建的箭头函数不需要块,我们可以简化它:

// The parenthesis are added because the syntax () => {} is not valid.
(({c}) => ({ c: c }))(data)

最后,我们可以使用短对象语法使其与原始对象完全相同。

(({c}) => ({ c }))(data)

因此,此函数生成一个 { c: <value> } 对象,因此您可以使用扩展运算符将其合并到您正在构建的对象中。