Destructuring Assignment In Function Call While Preserving The Object
Solution 1:
TL;DR
Objects - losing properties:
letf=({a:x,...o})=> {
console.log(o);console.log(x);
};f({a:0,b:1,c:2});//x is:0//o is: { b:1, c:2 }
Objects - preserving properties:
letf=(o)=> {
let { a:x } =o;console.log(o);console.log(x);
};f({a:0,b:1,c:2});//x is:0//o is: { a:0, b:1, c:2 }
Arrays - losing elements:
letf = ([x, ...a]) => {
console.log(a);
console.log(x);
};
f([0, 1, 2]);
// x is: 0// a is: [1, 2]
Arrays - preserving elements:
letf = (a) => {
let [x] = a;
console.log(a);
console.log(x);
};
f([0, 1, 2 ]);
// x is: 0// a is: [0, 1, 2]
Note that the examples above that preserve properties put the same object in o
(or array in a
) that was used when calling the function, not a copy. To use a shallow copy you can use the examples below:
Objects - preserving properties, creating a new object:
letf=({...o})=> {
let { a:x } =o;console.log(o);console.log(x);
};f({a:0,b:1,c:2});//x is:0//o is: { a:0, b:1, c:2 }
Arrays - preserving elements, creating a new array:
letf = ([...a]) => {
let [x] = a;
console.log(a);
console.log(x);
};
f([0, 1, 2]);
// x is: 0// a is: [1, 2]
Explanation
If you want to preserve all of the properties of the original object in o
then you need the explicit destructuring step in the body of your function: let { a: x } = o;
but if you want to preserve only those properties that were not put into x
then you may be able to use the destructuring as described below (in the future when it's supported). See Examples below for details.
Note that I originally assumed that you want destructuring as you would get when destructuring arrays - but maybe that's not what you want - thanks to Karen Grigoryan for pointing it out in the comments.
A syntax that should logically work would be not this:
letf = (o: { a: x }) => {
console.log(o);
console.log(x);
};
but this:
letf = ({ a: x, ...o }) => {
console.log(o);
console.log(x);
};
(But I would be (positively) surprised if that worked natively on any platform today or even in transpilers. This would need support for rest operator in object destructuring combined with unpacking fields from objects passed as function parameters. Theoretically there's no reason it shouldn't work. In practice it likely doesn't.)
Note that ({ a: x, ...o }) => ...
when invoked as f({ a: 0, b: 1 })
would put only { b: 1 }
in o
and would put 0
in x
- just like ([x, ...a]) => ...
when invoked as f([0, 1])
would put only [1]
in a
and would put 0
in x
.
This means that using destructuring with rest parameters - for objects and arrays alike - would not preserve the entire array or object in the rest variable but only that data that was not explicitly captured otherwise.
This means that no matter if you're destructuring arrays or objects, you need to put the explicit destructuring step in the body of your functions instead of relying on the parameter syntax if you want to have the original array or object intact.
See:
- Rest_in_Object_Destructuring on MDN
Solution 2:
No, it is not possible, consider:
var obj = {a:0}
functionf (o: {a:x}) {} // not valid - unexpected token :functionf ({a}) {} // valid a === 0functionf ({a:x}) {} // valid x === 0, a is undefined - probably no use for this
The best you can do with the ES6 implementation is get access to nested props, not a reference to the object itself as well as nested props.
(would love to be proven wrong though, this is a feature I have looked for as well)
Solution 3:
For nested object destructuring you can use an assignment operator to extract the nested reference value.
let {
o,
a = o.a
} = {
o: {
a: 'x'
}
}
console.log(o);
console.log(a)
Similarly, you can destructure the function caller
constf = ({ o,a=o.a } = {a:y}) => {
console.log(o)
console.log(a)
};
f({o:{a: 0 }});
Post a Comment for "Destructuring Assignment In Function Call While Preserving The Object"