En_On
En_On

Reputation: 15

"Uncaught ReferenceError: a is not defined" instead of "ReferenceError: Cannot access 'a' before initialization"

In this simple code, since the variable b is a let variable and i am trying to log() its value, I was expecting a reference error that said: cannot access 'a' before initialization,

but instead i am getting the error: Uncaught ReferenceError: a is not defined

console.log(a);
let a=10;
var b=19;

a screenshot of the code and the error-->

i ran the same code in online js editors and they give the expected error, i am confused now : the same code on an online editor with different error

Upvotes: 1

Views: 979

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1075417

ReferenceError: a is not defined means that the identifier a isn't declared at all in the current scope. That's clearly not the case in the code you've shown, suggesting either that the error isn't from the code shown (prehaps a previous run?) or that the code is being executed in an unusual way, such as in a REPL like the browser console. REPLs often execute the code in a slightly different way than it would be if it were run as part of a program, so it's generally best not to worry too much about this kind of difference between a REPL and non-REPL environment. Your screenshot doesn't look like a REPL, though. Here's an example of "is not defined":

console.log(a);

ReferenceError: Cannot access 'a' before initialization¹ means that a is declared in the scope, but you tried to use it before it was initialized, when it was in the Temporal Dead Zone. That's the correct error for the code shown when executed in the normal way (not in a REPL), because let a exists in the same scope as the console.log(a) above it, and so the binding (variable) is created but not initialized before the console.log statement attempts to access it. Here's your code at global scope, making it easy for people to see that this is the correct error:

console.log(a);
let a=10;
var b=19;


¹ That's V8's error (Chromium browsers, Node.js, Deno, ...). SpiderMonkey (in Firefox and such) says ReferenceError: can't access lexical declaration 'a' before initialization instead. JavaScriptCore (Safari, Bun) says ReferenceError: Cannot access uninitialized variable.


Another posted answer suggests that the difference relates to using a block statement or not using one, in part because MDN's page on the error is a bit misleading. That's incorrect, no block statement is required. (I raised an issue for it, and my PR was merged; the page has been corrected now.) The specification's description of the relevant operation (GetBindingValue) of an environment record (in this table) makes no distinction between records created for blocks, specifically, vs. other kinds of environment records (global, modules, function, ...). To be sure, I've verified that the three major JavaScript engines (V8, SpiderMonkey, and JavaScriptCore) all behave as described above with the OP's code at global scope (no block statement required), giving the error about an uninitialized variable, not the "not defined" error. You can try a Chromium browser or Firefox on the snippet above to check for yourself. (You might be able to with Safari on a Mac as well. Unfortunately, iOS Safari just reports a script error. I have verified it by directly executing JavaScriptCore, since I don't have a Mac.)

Upvotes: 2

Alex Borodin
Alex Borodin

Reputation: 2034

According to error docs it happens within any block statement

Since you don't have block statement, JS fires another error.

enter image description here

I suppose that in online editor, the code is executed by another code, so there could be block statement outside the "file".

Upvotes: -1

Related Questions