Variables, Types, and Collections23% of the exam

Declaring variables with var, let and const

How var, let and const differ in scope, hoisting, the temporal dead zone, re-declaration and reassignment, why const does not freeze objects, and the var-in-a-loop closure trap the exam loves.

Official exam objective
Given a scenario, write code to create variables and initialize them correctly.

~7 min read · 12 practice questions ·

What the exam expects

  • Predict what a snippet logs or throws when a variable is read before, inside or after the block that declares it with var, let or const.
  • Choose the keyword that lets the code run: let for values assigned later, const with a single-expression initializer otherwise.
  • Explain why const objects and arrays can still be changed, and what Object.freeze() adds (and does not).
  • Fix the classic var-in-a-loop closure bug, and spot implicit globals and duplicate declarations.
  • Initialize several variables at once with destructuring, including renames, nesting and defaults.
  • Key terms: declaration (let x, makes the name usable); initializer (= 42, the first value); block scope (visible only inside the nearest { }); hoisting (var declarations processed before any code runs); temporal dead zone (TDZ) (from the start of the scope until a let/const line runs, reading the name throws ReferenceError).

Key facts

var scope
Detail
Function (or script/module); blocks do not limit it
let/const scope
Detail
Nearest enclosing block
var read before its line
Detail
undefined (declaration hoisted, value not)
let/const read before its line
Detail
ReferenceError, even with typeof (TDZ)
const x;
Detail
SyntaxError: Missing initializer in const declaration
Reassigning a const
Detail
TypeError: Assignment to constant variable
Duplicate let in one scope
Detail
Parse-time SyntaxError; nothing in the script runs
Duplicate var
Detail
Allowed, even in strict mode
Undeclared assignment
Detail
Sloppy: creates a global; strict: ReferenceError
Object.freeze()
Detail
Shallow; sloppy writes fail silently, strict writes throw
let in a for header
Detail
New binding each iteration
Destructuring default
Detail
Used for missing or undefined, not null
Sources for this section (9)
  • Why does `console.log(x); var x = 3;` log `undefined` while the same line with `let` throws?
  • When must you use `let` instead of `const` for a value chosen in an `if...else`?
  • What does `let a = b = 5;` inside a sloppy-mode function do to `b`?
  • Why does `let i` in a `for` header fix callbacks that all log the final value?
  • Which value does `const { lang = 'en' } = { lang: null }` give `lang`?

The questions are free to read. Answers with their sources and self-grading are included with the pack.

Keep reading with the JavaScript Developer pack

  • Core concepts
  • Exam traps
  • Worked scenario

The pack includes:

  • All 24 lessons of the JavaScript Developer guide, with reading progress
  • Interactive decision walks and step-by-step sequence steppers
  • Inline practice questions and one-click topic practice (12 questions for this lesson)
  • An official source cited for every claim
  • An AI tutor that answers from the guide
  • Unlimited timed practice exams

Practice for the JavaScript Developer exam