今天,我必须合并两个对象,挑选一个对象的属性。a
并将它们放在一个对象中 b
. 我不明白为什么第一个语法语句不能用,而第二个却能用。
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.netLjb7ndp46
在第二个方法中,你正在创建一个IIFE(立即调用函数表达式)。
在第二种方法中,你正在创建一个IIFE(立即调用的函数表达式)。MDN文件方法1中的IIFE是 "立即调用的函数表达式(Immediately Invoked Function Expression)","IIFE是一个JavaScript函数,一旦被定义就会运行"。方法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> }
对象,因此您可以使用传播操作符将其合并到您正在构建的对象中。