user51462
user51462

Reputation: 2082

JS - Auto-initialisation behaviour of `let` vs `var`

In 'Chapter 5: The (Not So) Secret Lifecycle of Variables' of 'You Don't Know JS Yet', the section titled "Uninitialized Variables (aka, TDZ)" says that the only way to initialise an uninitialised let variable is with an assignment attached to a declaration statement (because an assignment by itself is insufficient). This is illustrated by the following example.

Example 1:

let studentName = "Suzy";
console.log(studentName);   // Suzy

In the next example, the declaration and initialisation is split up - the let variable is declared on line 1 and then initialised on line 2:

Example 2:

let studentName;
// or:
// let studentName = undefined;
    
studentName = "Suzy";

console.log(studentName);
// Suzy

Under this example, there is a callout that reads:

That's interesting! Recall from earlier, we said that var studentName; is not the same as var studentName = undefined;, but here with let, they behave the same. The difference comes down to the fact that var studentName automatically initializes at the top of the scope, where let studentName does not.

Question 1:

I'm not sure how Example 2 above demonstrates that let studentName; and let studentName = undefined; are equivalent. Earlier in the chapter, the section titled "Redeclaration?" uses the following example to illustrate that var studentName; is not the same as var studentName = undefined;:

Example 3:

var studentName = "Frank";
console.log(studentName); // Frank

var studentName;
console.log(studentName); // Frank <--- still!

// let's add the initialization explicitly
var studentName = undefined;
console.log(studentName); // undefined <--- see!?

In the above example, the second studentName declaration is basically a no-op since studentName has already been declared. But how does this relate to the let example (example 2)? i.e. How does example 2 show that let studentName; and let studentName = undefined; behave the same?

Question 2:

The second sentence of the callout above says, "The difference comes down to the fact that var studentName automatically initializes at the top of the scope, where let studentName does not." But doesn't let automatically initialises to undefined if no value is specified at the time of declaration (see here)?

Edit:

My bad - regarding Question 2, the second sentence of the callout does make sense. The specs say that if a let declaration does not have an initialiser expression, then that let-declared variable will be assigned a value of undefined when that let declaration is evaluated. Whereas if a var declaration is made without an initialiser, then that var-declared variable will be assigned undefined when it is created (see).

However, I'm still unsure about Question 1.

Upvotes: 0

Views: 649

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 371233

One of the important differences:

The difference comes down to the fact that var studentName automatically initializes at the top of the scope, where let studentName does not.

is not illustrated by the example snippets in your question, since you don't try to access the variables declared with let before they're declared.

In the above example, the second studentName declaration is basically a no-op since studentName has already been declared. But how does this relate to the let example?

With let, re-declarations are not permitted - rather, there must be a single statement in the code somewhere where the variable name can be determined to come out of the temporal dead zone and get referenced by other parts of the code. Until a variable has been fully initialized - that is, until the interpreter has run across the let someVarName line (no matter whether something is assigned to it with = or not) - the variable name cannot be assigned to or retrieved.

Aside for that, let someVarName is pretty similar to var someVarName - let will assign a value of undefined to the variable at that moment, and the var will give the variable a value of undefined at the beginning of the scope.

"The difference comes down to the fact that var studentName automatically initializes at the top of the scope, where let studentName does not." I'm not sure what this means as I always thought let automatically initialises to undefined if no value is specified at the time of declaration

See this for an example:

// Not permitted:
console.log(studentName); // Error
let studentName;

Compare to:

// OK
console.log(studentName);
var studentName;

With let, you cannot reference said variable until the interpreter has run across the let someVarName line.

Upvotes: 1

Related Questions