Closed jseter closed 5 years ago
I would assume it would work like any variable reference - it it ended up as nullish, then the chain would be short circuited.
I think it'd be nice for it to throw an error, similar to the following reference error:
$ node
> x.y
ReferenceError: x is not defined
at repl:1:1
at ContextifyScript.Script.runInThisContext (vm.js:44:33)
at REPLServer.defaultEval (repl.js:239:29)
at bound (domain.js:301:14)
at REPLServer.runBound [as eval] (domain.js:314:12)
at REPLServer.onLine (repl.js:433:10)
at emitOne (events.js:120:20)
at REPLServer.emit (events.js:210:7)
at REPLServer.Interface._onLine (readline.js:278:10)
at REPLServer.Interface._line (readline.js:625:8)
> x = undefined
undefined
> x.y
TypeError: Cannot read property 'y' of undefined
at repl:1:2
at ContextifyScript.Script.runInThisContext (vm.js:44:33)
at REPLServer.defaultEval (repl.js:239:29)
at bound (domain.js:301:14)
at REPLServer.runBound [as eval] (domain.js:314:12)
at REPLServer.onLine (repl.js:433:10)
at emitOne (events.js:120:20)
at REPLServer.emit (events.js:210:7)
at REPLServer.Interface._onLine (readline.js:278:10)
at REPLServer.Interface._line (readline.js:625:8)
At least for me, something like x.y
is usually a typo if x
hasn't been defined, and I'd like it to throw a ReferenceError
.
Is that what you mean?
This should definitely be throwing a reference error for undeclared variables.
if x.y already throws a ReferenceError, so would x??.y - the optional chain applies to the member access, not to the lookup of x itself.
You’re right. It should probably only deal with defined values/nullish and continue to throw in this case. For the most part this question is about being explicit in the proposal whether it handles them in any special way, but perhaps that could also be made clear by the grammar for acceptable inputs. Thanks
I think it's explicit that it doesn't handle the a
any differently in a??.b
etc, because it only addresses the .b
part.
See https://github.com/tc39/proposal-nullish-coalescing/issues/13 and https://github.com/tc39/proposal-optional-chaining/issues/17#issuecomment-360300330 for some previous discussion on this.
CoffeeScript chose to make someUndeclaredVariable?.foo
return undefined
rather than crashing, which is occasionally useful and used in practice (e.g. window?.foo
when you don't know if you're running in a browser). The big downside is that it silently ignores misspelled variable names (or other mistakes) in the 99% case when you're using a variable that you meant to declare, so I think the right behavior in JS is to throw ReferenceError if the variable is undeclared.
Agree with the points in this thread. Optional chaining isn't a general error suppression mechanism but rather much more specific.
Should there be any definition for what occurs if the root of the expression does not exist?
i.e. code expects a global namespace 'cordova', but in some situations it may not be defined. normally you could only check via an initial
typeof cordova !== "undefined"
unless you are able to get an instance of the global object to use as your root in the expression instead.