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.