getify / You-Dont-Know-JS

A book series on JavaScript. @YDKJS on twitter.
Other
177.97k stars 33.41k forks source link

ES6 & Beyond, Chapter 2: Syntax, using object destructuring to set defaults for a nested object's properties example #1700

Closed OahMada closed 3 years ago

OahMada commented 3 years ago

Yes, I promise I've read the Contributions Guidelines (please feel free to remove this line).


Please type "I already searched for this issue": I already searched for this issue Edition: (1st or 2nd) 1st Book Title: ES6 & Beyond Chapter: Syntax Section Title: Nested Defaults: Destructured and Restructured Question: The example of setting defaults for a nested object's properties with the help of object destructuring:

({
    log: {
        warn: config.log.warn = defaults.log.warn,
        error: config.log.error = defaults.log.error
    } = {}
} = config);

I couldn't figure out why the trailing part ={} is necessary if at all, because removing it makes no different to the result, and it doesn't make any sense logically. Let's consider a more concise one, e.g. ({log: AA = {}} = config), the way I reason about it is that if there's no log property within config, then variable AA is set to {}; however, you clearly not able to set

{
    warn: ...,
    error: ...
}

to {}, right? Because it's not a valid assignment expression, or is it? Even if it's syntactically valid, we know that config.log is already set to {} with config.log = config.log || {}; in the code listing, it still seems unnecessary.

So, what role exactly the ={} part is playing and why it's necessary? Or is it a mistake? Thanks.

getify commented 3 years ago

...is necessary if at all, because removing it makes no different to the result

Doesn't matter here, but in general all nested destructuring patterns need a default so as to not fail if the nested object/array to be destructured is actually missing. This is a consistency of coding style sort of thing.

getify commented 3 years ago

Because it's not a valid assignment expression, or is it? Even if it's syntactically valid

Yes, this would be syntactically valid, but not as useful as one might expect:

({
   log: {
      // ..
   } = { whatever: 42 }
} = config);
OahMada commented 3 years ago

Thanks for your explanation, my mind is clear now.