It is known that structuring is nothing more than syntactic sugar for common operations involving access to objects (which includes the indexing of arrays).
Therefore, the code:
function logName({ name = 'Anonymous' }) {
console.log(name);
}
IS equivalent to something like:
1 | function logName(_ref) {
2 | const _ref$name = _ref.name;
3 | const name = _ref$name === undefined ? 'Anonymous' : _ref$name;
4 |
5 | console.log(name);
6 | }
Adapted from Babel Playground.
If you pay attention to line 2, you will see that a property access occurs to the object passed as argument. In this case, it occurs _ref.name
.
From there, we can reach two conclusions:
- The standard value in the breakdown refers to property, and not to the argument (possibly optional) function.
- If argument not provided,
_ref
(the first parameter) will be undefined
. And, as usual Javascript, undefined.name
(or any other access to property on undefined
or null
) spear one TypeError
.
Thus, if there is the possibility of the argument being optional, it is necessary to provide a default value for the parameter as well. Something like:
// ↓↓↓↓
function logName({ name = 'Anonymous' } = {}) {
console.log(name);
}
In the above example, we define a new literal object "empty" as the default value for the first parameter of function logName
. It’s important to understand the difference:
- A string
'Anonymous'
is a default value for a property of the object.
- The literal "empty"
{}
is a default value for the first argument of function.
They are quite different, because there is no point in setting default value for a property of an object that does not even exist. Just as a last query to systematize: how Javascript could evaluate whether the property exists or not (to then assign a possible default property value) if the parameter is undefined
?
Just as a curiosity, when default value for the property is provided in the breakdown, the error message is something like:
Cannot read property 'name' of undefined
But when you don’t provide default property value, the message is a little more understandable:
Cannot destructure property 'name' of 'undefined' as it is undefined.
Behold:
try {
// Sem valor padrão:
// Cannot destructure property 'name' of 'undefined' as it is undefined.
const { name } = undefined;
} catch ({ message }) {
console.log(message);
}
try {
// Com valor padrão:
// Cannot read property 'name' of undefined
const { name = 'Default' } = undefined;
} catch ({ message }) {
console.log(message);
}