var, let, and const in JavaScript

Understanding the differences between var, let, and const is crucial for proper variable declaration and scope management in JavaScript.

var Declaration

// Function scope
function example() {
  var x = 1;
  if (true) {
    var x = 2;  // same variable
    console.log(x);  // 2
  }
  console.log(x);    // 2
}

// Hoisting
console.log(hoisted);  // undefined
var hoisted = 'value';

// Global object property
var globalVar = 'I am global';
console.log(window.globalVar);  // 'I am global'

// Re-declaration allowed
var user = 'John';
var user = 'Jane';  // allowed

let Declaration

// Block scope
function example() {
  let x = 1;
  if (true) {
    let x = 2;  // different variable
    console.log(x);  // 2
  }
  console.log(x);    // 1
}

// Temporal Dead Zone (TDZ)
console.log(blocked);  // ReferenceError
let blocked = 'value';

// No global object property
let globalLet = 'I am not global';
console.log(window.globalLet);  // undefined

// No re-declaration
let user = 'John';
let user = 'Jane';  // SyntaxError

const Declaration

// Must be initialized
const EMPTY;  // SyntaxError

// Cannot be reassigned
const PI = 3.14;
PI = 3.14159;  // TypeError

// But objects are mutable
const user = { name: 'John' };
user.name = 'Jane';  // Allowed
user = { name: 'Jim' };  // TypeError

// Array mutation
const numbers = [1, 2, 3];
numbers.push(4);     // Allowed
numbers = [5, 6, 7]; // TypeError

// Object freeze for immutability
const frozenUser = Object.freeze({
  name: 'John'
});
frozenUser.name = 'Jane';  // No effect in strict mode

Choosing Between Them

// Use const for values that shouldn't change
const API_KEY = 'abc123';
const CONFIG = Object.freeze({
  endpoint: 'https://api.example.com'
});

// Use let for values that need to change
let counter = 0;
counter++;

// Avoid var in modern JavaScript
// Bad
var index = 0;
// Good
let index = 0;

// Loop example
for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1);
} // Prints: 0, 1, 2

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1);
} // Prints: 3, 3, 3

Common Interview Follow-up Questions

  1. Why was let introduced when we already had var?
  2. What is the Temporal Dead Zone?
  3. How do var, let, and const affect the global object?
  4. When would you use const vs let?

Best Practices

  • Use const by default
  • Use let when you need to reassign
  • Avoid var in modern code
  • Be aware of block scope vs function scope
  • Consider Object.freeze for true constants
  • Understand TDZ implications

Edge Cases and Gotchas

// const with objects
const obj = {};
obj.prop = 'value';  // Works
Object.defineProperty(obj, 'readonly', {
  value: 'cant change this',
  writable: false
});

// let in loops
for (let i = 0; i < 3; i++) {
  let i = 10;  // Shadows loop variable
  console.log(i);  // 10, 10, 10
}

// var in modules
var moduleVar = 'not global';
console.log(window.moduleVar);  // undefined in modules