Variables
Variables are declared with var, let or const. They differ in scope,
reassignment and behavior before the declaration.
var | let | const | |
|---|---|---|---|
| Scope | function | block | block |
| Reassignment | yes | yes | no |
| Redeclaration | yes | no | no |
| Initializer | optional | optional | required |
| Access before the line | undefined | ReferenceError | ReferenceError |
| Global object property | yes | no | no |
Use const by default, let when the variable is reassigned, and avoid var.
Details
Declaration and Initializer
var myVariable = 10;
// `var myVariable` is the declaration, `= 10` is the initializer
Identifier names:
- can include letters, digits,
_and$; - can't begin with a digit;
- are case-sensitive (
myVarandMyVarare different variables); - are written in camelCase by convention.
var1
- Scoped to the function, or global when declared outside any function.
Blocks (
if,for) do not limit it. - Without an initializer the value is
undefined. - At the top level of a script it adds a property to the global object. In a module it is module-scoped.
let and const2
- Scoped to the block: a pair of curly braces, including
ifandfor. constcan't be reassigned, so the initializer is required.constdoes not make the value immutable. The variable holds a reference to the object, and the object itself can still be changed.
Hoisting and the Temporal Dead Zone
- All declarations are registered when the scope is created, before any code runs. This is called hoisting3.
varis hoisted with the valueundefined. The assignment stays in place.letandconstare hoisted too, but can't be read until the declaration is executed. This period is the temporal dead zone (TDZ).- The TDZ depends on the order of execution, not on the position in the file. A function may use a variable declared below it if it is called after the declaration.
See Execution Context.
Example
function show() {
console.log(value);
}
show(); // ReferenceError: Cannot access 'value' before initialization
const value = 1;
show(); // 1
const user = { name: 'Ann' };
user.name = 'Bob'; // OK: the same object is mutated
user = {}; // TypeError: Assignment to constant variable.
Follow-up Questions
- What does a loop with
varandsetTimeoutprint? See Closures. - How do you make an object immutable? See Objects.
- What happens when you assign to an undeclared variable? In strict mode it is a
ReferenceError; otherwise a global variable is created.
Common Mistakes
- "
constmakes the value constant." Only the binding is constant. - "
letandconstare not hoisted." They are, but they stay in the TDZ. - "
varis block-scoped." It ignores blocks and is visible in the whole function.