Today I had to merge two objects, picking the properties of an object a
and placing them in an object b
. I can't understand why the first syntax/statement is not working, while the second one is.
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);
You can try the code on https://jsfiddle.net/Ljb7ndp4/6/
In the second method you are creating an IIFE (Immediately Invoked Function Expression).
From MDN docs, "an IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined". The IIFE on method 2 is returning an object like {c: <value>}
. As objects support the spread operator, you are able to use it in the object definition.
To visualize it in your code, you can assign the result of the IIFE to a variable and print the result on console.
const val = (({c}) => ({c}))(data)
console.log(val) // { c: 3 }
The arrow function syntax, in this case, makes a little bit harder to visualize what is happening, but the code:
(({c}) => ({c}))(data);
is a short version of this one, which is better readable, in my opinion.
(function(arg) {
return { c: arg.c }
})(data);
So, we can convert it to arrow function to understand all the transformations, step by step.
Initially we can convert the function to use the arrow function syntax:
((arg) => {
return { c: arg: c }
})(data)
Then we can destructur c
from the received argument.
(({c}) => {
return { c: c }
})(data)
As the created arrow function does not require a block, we can simplify it:
// The parenthesis are added because the syntax () => {} is not valid.
(({c}) => ({ c: c }))(data)
And finally, we can use the short object syntax to make it exactly as the original one.
(({c}) => ({ c }))(data)
So, this function generates a { c: <value> }
object, and therefore you can use the spread operator to merge it in the object you are building.