Understanding var, let, & const

JavaScript provides three ways to declare variables: var, let, and const. Each has different scoping rules and characteristics.

Var

var is function-scoped and can be redeclared.

var user = 'Hunter';
var user = 'Macias'; // No error
console.log(user); // 'Macias'

Quirks and Special Cases

var declarations are hoisted to the top of their scope.

console.log(user); // undefined
var user = 'Hunter';

var allows you to declare the same variable multiple times within the same scope.

Let

let is block-scoped and cannot be redeclared within the same scope.

let user = 'Hunter';
// let user = 'Macias'; // Error: Identifier 'user' has already been declared
user = 'Macias'; // Valid reassignment
console.log(user); // 'Macias'

let declarations are not hoisted in the same way as var. They are hoisted but not initialized, leading to a "temporal dead zone".

// console.log(user); // Error: Cannot access 'user' before initialization
let user = 'Hunter';

Const

const is block-scoped and cannot be reassigned or redeclared. It must be initialized during declaration.

const user = 'Hunter';
// user = 'Macias'; // Error: Assignment to constant variable
console.log(user); // 'Hunter'

const declarations are also subject to the "temporal dead zone".

Block Scope

if (true) {
  let blockScoped = 'Inside block';
  console.log(blockScoped); // 'Inside block'
}
// console.log(blockScoped); // Error: blockScoped is not defined

const objects and arrays can have their contents modified.

const user = { name: 'Hunter' };
user.name = 'Macias'; // Allowed
console.log(user.name); // 'Macias'

const colors = ['red', 'blue'];
colors.push('green'); // Allowed
console.log(colors); // ['red', 'blue', 'green']

When to Use

  • var: Rarely used; prefer let or const.
  • let: Use for variables that may change.
  • const: Use for variables that shouldn't change.

Function Scope vs Block Scope

function exampleFunction() {
  var functionScoped = 'Function Scope';
  if (true) {
    var functionScoped = 'Still Function Scope';
    let blockScoped = 'Block Scope';
    console.log(blockScoped); // 'Block Scope'
  }
  console.log(functionScoped); // 'Still Function Scope'
  // console.log(blockScoped); // Error: blockScoped is not defined
}

exampleFunction();

Temporal Dead Zone

// Uncommenting the lines below will cause an error
// console.log(user); // Error: Cannot access 'user' before initialization
// console.log(admin); // Error: Cannot access 'admin' before initialization

let user = 'Hunter';
const admin = 'Macias';
console.log(user); // 'Hunter'
console.log(admin); // 'Macias'

FAQ

Q: What is variable hoisting?

A: Variable hoisting refers to the behavior in JavaScript where variable declarations are moved to the top of their containing scope during the compile phase. This means you can use a variable before it is declared, but it will be `undefined` if you do so with `var`. With `let` and `const`, accessing the variable before declaration results in a ReferenceError due to the temporal dead zone.

Q: Can I reassign a `const` variable?

A: No, a `const` variable cannot be reassigned once it is initialized. However, if the `const` variable is an object or array, the properties of the object or the elements of the array can still be modified.

Q: What is the temporal dead zone?

A: The temporal dead zone is the period of time during which a `let` or `const` variable is hoisted but not yet initialized. During this time, any attempt to access the variable will result in a ReferenceError.

Q: Should I always use `const`?

A: It's a good practice to use `const` for variables that should not be reassigned to ensure immutability. Use `let` for variables that will change. Avoid using `var` unless you have a specific reason to use function-scoped variables.

Understanding the differences between var, let, and const helps you write cleaner, more predictable code. Use let and const to avoid issues related to variable scoping and reassignment.