Redeclaration with var works but not with let in Chrome Snippets

Viewed 530

I started to learn JavaScript and I use Snippets or just Console in Google Chrome. I don't understand one thing. When I run snippet like:

let x = 5;
console.log(x);

multiple times. Everything is ok, but when I first run this:

var x = 5;
console.log(x);

and then I change the code to use let:

let x = 5;
console.log(x);

I get error SyntaxError: Identifier 'x' has already been declared and I don't understand why. I assume that variables declared with let are somehow "volatile", but variables declared with var are associated with window object, so they are "non volatile"? Or in more general: are declarations in global environment's declarative environment record wiped out after script execution but declarations stored in global environment's object environment record are not? When I run snippet in Google Chrome Snippets/Console multiple times, does it run in same Execution Context or it is recreated with new global environment each time when I push Run button?

3 Answers

Which Chrome version are you using? Since Chrome 80 you can redeclare let variables in the browser console. But keep in mind this only exists because of testing purposes. Real JavaScript engines (Node.js, Chrome besides the DevTools, etc.) will still throw an error.

That var can be redeclared is normal, because it is differently scoped. This was one of the reasons let were added with ES6. You can read more about var vs. let here.

You can wrap all of your code in brackets.

{
let x = 5;
console.log(x);
}

JavaScript allows you to wrap any code in brackets. The brackets will create a unique scope for your let variables each time you run the snippet.

Multiple declarations of the same var variable in the same scope are ignored. This is not the case with let (and also const) as multiple declaration in the same scope are not ignored, thus causing the second declaration to fail.

Consider the following:

var x = 1;
var x = 2;

and the following:

let x = 1;
let x = 2;

In the first example, the interpreter sees the code as:

var x;
x = 1;
x = 2;

The seconds example stays the same, because of the let keyword.

Although all variables are technically hoisted, they are not evaluated the same. From https://www.ecma-international.org/ecma-262/9.0/index.html#sec-let-and-const-declarations:

A var statement declares variables that are scoped to the running execution context's VariableEnvironment. Var variables are created when their containing Lexical Environment is instantiated and are initialized to undefined when created.

Meaning var declaration is evaluated once its context is instantiated. let however, is only evaluated once the declaration in the code is reached.

Related