Error unstructurating value in function: Typeerror: Cannot read Property of Undefined

Asked

Viewed 227 times

1

I would like to understand why this mistake happens:

Uncaught TypeError: Cannot read property 'name' of undefined
    at logName (<anonymous>:1:24)
    at <anonymous>:5:1

Code:

function logName({ name = 'Anonymous' }) {
  console.log(name);
}

logName();

If I am providing a standard value for name, I think Javascript should understand that this is an optional argument and not throw error.

However, it seems that’s not quite what happens. Why?

1 answer

1


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);
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.