2

in a node repl or browser console:

> ({})?.a
undefined
> (null)?.a
undefined
> (null)?.a.b
undefined
> ({})?.a.b
Uncaught TypeError: Cannot read properties of undefined (reading 'b')

if (anything)?.a is undefined then why does the undefined that (null)?.a evaluates to NOT throw an error when I read its non-existent properties?

9
  • 1
    ({}) is not undefined, but there's no "a" property in that object so ({})?.a is undefined, just like ({a: 1}).b is undefined. Commented Feb 27, 2024 at 22:04
  • 3
    @HereticMonkey OP might have used the wrong word. Yes, of course that statement doesn't "return" anything. But nonetheless, it "evaluates to" undefined Commented Feb 27, 2024 at 22:06
  • 2
    In different words, the optional chaining operator only short circuits chained operators when the object or function to be called supplied as the left hand operand of .? is null or undefined. Since {} is neither of those, evaluation continues without short circuiting and throws the error for the same reason ({}}.a.b would throw attempting to look up the b property of undefined. Commented Feb 27, 2024 at 22:57
  • 2
    See: stackoverflow.com/q/61082928/5648954 Commented Feb 28, 2024 at 2:45
  • 1
    @derpirscher I see. I kinda agree with traktor (the reopener) though, this Q&A doesn't answer the question at all, and doesn't explain the difference between (null)?.a.b and (null?.a).b. The one NickParsons dug up is more suited as a duplicate, though all the info there is in the comments not the answer. Commented Feb 28, 2024 at 6:42

2 Answers 2

4

It's working that way to allow you to check if an object exists, and then access multi-level properties if it does without needing a huge tree of checks against every level of the object. The case with (null)? is repeatable in two more ways that illustrate the principle:

(undefined)?.a.b.c.d 
({})?.a?.b.c.d

Both of those will also return undefined without throwing an error. As long as you've triggered a fail state with ? already, it will let you reference subproperties safely to as many layers as you like

({})?.a.b throws an error because {} is defined and passes the check, but then you're not checking whether a is undefined before trying to access its properties

Sign up to request clarification or add additional context in comments.

Comments

2

why does the undefined that (null)?.a evaluates to NOT throw an error when I read its non-existent properties?

It would:

> (null?.a).b
Uncaught TypeError: Cannot read properties of undefined (reading 'b')
> const temp = null?.a;
> temp.b
Uncaught TypeError: Cannot read properties of undefined (reading 'b')

The difference from that to null?.a.b is that the optional chaining operator short-circuits the entire property access (and method call) chain, stopping evaluation and just returning undefined.

1 Comment

so... null?.a and null?.a.b both evaluate to undefined because a and a.b are irrelevant. Everything after the ?. is ignored. Thanks for the clear answer!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.