- Scope: var has function scope or global scope, meaning it is accessible throughout the function in which it is declared, or globally if declared outside any function.
- Hoisting: var declarations are hoisted to the top of their scope, but the assignments are not. This means the variable is accessible before its declaration, but its value is undefined until the assignment is executed.
- Re-declaration: Variables declared with var can be re-declared within the same scope without causing an error.
function exampleVar() {
console.log(x); // undefined due to hoisting
var x = 10;
console.log(x); // 10
var x = 20; // re-declaration is allowed
console.log(x); // 20
}
- Scope: let has block scope, meaning it is only accessible within the block (enclosed by {}) in which it is declared.
- Hoisting: let declarations are hoisted, but unlike var, they are not initialized until the declaration is evaluated. This leads to a "temporal dead zone" from the start of the block until the declaration is encountered.
- Re-declaration: Variables declared with let cannot be re-declared within the same scope, which helps prevent accidental re-declarations and bugs.
function exampleLet() {
console.log(x); // ReferenceError: x is not defined
let x = 10;
console.log(x); // 10
// let x = 20; // SyntaxError: Identifier 'x' has already been declared
}
- Scope: const also has block scope, similar to let.
- Hoisting: Like let, const declarations are hoisted but are not initialized until the declaration is encountered, leading to a "temporal dead zone."
- Re-declaration and Re-assignment: Variables declared with const cannot be re-declared or re-assigned. The value assigned to a const variable is immutable (cannot be changed). However, if the const variable holds an object or array, the contents of the object or array can still be modified.
function exampleConst() {
const y = 10;
console.log(y); // 10
// y = 20; // TypeError: Assignment to constant variable
const z = { a: 1 };
z.a = 2; // Allowed, because object properties can be changed
console.log(z); // { a: 2 }
}
- var: Function-scoped or globally scoped, hoisted with undefined initialization, can be re-declared.
- let: Block-scoped, hoisted without initialization (temporal dead zone), cannot be re-declared.
- const: Block-scoped, hoisted without initialization (temporal dead zone), cannot be re-declared or re-assigned (but mutable objects).