I ran these experiments in the Chrome console:
a = {}
-> {}
a.n.n.n.n.n.n.n
-> Uncaught TypeError: Cannot read properties of undefined (reading 'n')
a?.n.n.n.n.n.n.n
-> Uncaught TypeError: Cannot read properties of undefined (reading 'n')
a?.n?.n.n.n.n.n.n
-> undefined
Based on my understanding of that operator, I would have expected an error unless all "dots" have a preceding question mark: The subexpression a?.n?.n
should result in undefined, and the subsequent .n
should crash. However, after doing ?.n
two times, something seems to change and reading the property n of undefined seems to be okay, which is obviously nonsense. So something else is probably going on.
One might think that ?.
shortcuts the whole remaining expression when evaluated on undefined, but this cannot be the case either, otherwise a single ?.
should be sufficient to achieve that.
How exactly does ?.
behave, and how does that behaviour explain the results I’m getting?
2
Answers
This is explained in the "Short Circuiting" chapter of the documentation, here
Especially the sentence following that first paragraph:
So this is documented behavior, and it does well explain the behavior you see, because in your example
a
is not undefined, and thus the first?.
is evaluated toa
and then the next expression the runtime sees, isa.n.n
.Quoting from the question:
Yes, that is exactly what is happening. From MDN:
When you access
a.b.c
ora?.b.c
a
evaluates to the empty objecta.b
evaluates to undefineda.b.c
throws an error because you are accessingc
property from undefined.Note that adding
?.
aftera
is unnecessary here becausea
is not nullish.But, in case of
a?.b?.c.d
ora.b?.c.d
a
evaluates to an object anda?.b
evaluates to undefined like before.a?.b?.c
: sincea.b
is undefined, it doesn’t access thec
property and short circuits here and returns undefined value for the entire expression