Let's say I have this set up:
const objA = { name: "Jacob", email: "[email protected]" };
const objB = { lastName: "Smith" };
Why can I do this:
const lastName = objA.lastName || objB.lastName;
But not this?
const { lastName } = objA || objB;
Was able to re-create above example in dev tools.
My real world application: I have "normal" and "legacy" account roles, and after querying both types of roles, I'd like to be able to do:
const { schoolAdmin } = account || legacyAccount;
... but instead have to do:
const schoolAdmin = account.schoolAdmin || legacyAccount.schoolAdmin;
Which is admittedly not a big deal, but I feel like there's something I'm missing and that I could use destructuring here. Jr dev, sorry if this is a dummy question! (Sometimes there is no account, and sometimes there is an account that doesn't have the schoolAdmin role! Likewise with legacyAccount.)
Your expression is trying to assign
lastNamefrom a property in the object returned from the sub-expression on the right side of the=assignment operator. That right side sub-expression,objA || objBevaluates toobjA, which has nolastNameproperty, so yourlastNamevariable receives a value ofundefined.You could either just use
objA, and provide a default value fromobjB, if the property doesn't exist inobjA:Or, you can spread
objAandobjBinto a single object, and destructure from that:When spreading, reverse the order. The last object spread overwrites values from the first object. So, if you want to prefer the value from
objA, listobjAlast.This spreading option provides a satisfying symmetry, but is likely to be less efficient. From a performance perspective, the first option is better. But, for me, personally, I think the code you don't like provides better clarity with performance as good as you can get:
This is completely unambiguous and performs no unnecessary operations.
It should also be pointed out that neither of my solutions is strictly equivalent to the non-destructuring approach. If
objA.lastNameis a falsy value besidesundefined, ("",null,0, orfalse), thenobjB.lastNamewould be used, whereas in both of my solutions, the falseyobjA.lastNamewould be used. Thanks to VLAZ for mentioning this in the comments.