Online Compiler logoOnline Compiler

JavaScript Tutorial

JavaScript Variables: var, let, const

Variable declarations control scope, mutation, and runtime behavior.

Most beginner and intermediate bugs in JavaScript come from incorrect variable usage.

Why We Need It

Correct variable semantics reduce hidden bugs and prevent accidental global leaks.

They also make async behavior easier to reason about and debug.

Syntax

var name = 'Asha';
let count = 0;
const MAX = 10;

Basic Example

1. Variable Declaration Differences

// var - function scope, redeclarable
if (true) {
  var x = 10;
}
console.log(x); // 10 (leaks outside block)

// let - block scope
if (true) {
  let y = 20;
}
...

var escapes blocks; let and const respect block boundaries.

Real World Example

2. Scope Differences

function testScope() {
  if (true) {
    var functionScoped = "visible in function";
    let blockScoped = "only in this block";
    const alsoBlockScoped = "also only here";
  }

  console.log(functionScoped); // works
  // console.log(blockScoped); // ReferenceError
  // console.log(alsoBlockScoped); // ReferenceError
...

var is function-scoped; let and const are block-scoped.

Multiple Use Cases

var, let, const: Declaration Keywords

JavaScript provides three ways to declare variables, each with different scoping and mutation rules.

var is function-scoped and can be redeclared; let is block-scoped and reassignable; const is block-scoped and cannot be reassigned.

Use const by default for immutable bindings, let when reassignment is needed, and avoid var in modern code.

Scope and Lifetime

Scope defines where a variable is accessible; lifetime describes how long it exists in memory.

var is function-scoped and can leak out of blocks. let and const are block-scoped and stay inside their braces.

Block scope prevents accidental leaks and improves predictability, especially in loops and conditionals.

Hoisting and Temporal Dead Zone

Hoisting moves declarations to the top of their scope, but not initializations.

var is hoisted and initialized to undefined, while let/const are hoisted but inaccessible until declared (TDZ).

TDZ prevents early access errors and helps catch bugs.

Reassignment and Mutation

Reassignment changes the binding; mutation changes the contents of an object or array.

const prevents reassignment but still allows mutation of object properties and array items.

For deep immutability, use Object.freeze or immutable update patterns.

Best Practices

Use const by default, let only when reassignment is necessary, and avoid var.

Declare variables close to usage and use clear, descriptive names.

Keep scopes small to reduce unexpected interactions.

More Examples

3. Hoisting Behavior

// var hoisting
console.log(a); // undefined
var a = 10;

// let/const temporal dead zone
// console.log(b); // ReferenceError
let b = 20;

// console.log(c); // ReferenceError
const c = 30;

var is hoisted with undefined; let/const create a temporal dead zone.

4. const with Objects

const config = { theme: "light" };
// config = { theme: "dark" }; // TypeError

config.theme = "dark"; // allowed
console.log(config.theme);

const prevents reassignment but allows object mutation.

Comparison

Without

// var leaks out of blocks
if (true) {
  var x = 1;
}
console.log(x); // 1

With

// let respects block scope
if (true) {
  let x = 1;
}
// console.log(x); // ReferenceError

Common Mistakes and Fixes

Using var in loops

Use let for loop variables to avoid closure bugs.

Assuming const means immutable

const prevents reassignment, not mutation. Use Object.freeze for immutability.

Accessing variables in TDZ

Declare variables before use to avoid ReferenceError.

Interview Questions

What is the difference between var and let?

var is function-scoped; let is block-scoped.

What is TDZ?

The temporal dead zone prevents access to let/const before declaration.

Does const make objects immutable?

No. It prevents reassignment, not mutation.

Practice Problem

Practice: Declare a const name and a let counter, then increment the counter.

const name = "Riya";
let count = 0;

// TODO: increment count and log name + count

One Possible Solution

const name = "Riya";
let count = 0;

count += 1;
console.log(name, count);

Frequently Asked Questions

Which keyword should I use by default?

Use const by default and let when reassignment is required.

Why avoid var in modern JavaScript?

var has function scope and hoisting behavior that can cause confusing bugs.

What is the temporal dead zone?

It is the time before let/const declaration where the variable exists but cannot be accessed.

Can const arrays be changed?

Array contents can be changed, but the variable cannot be reassigned to a new array.

Try It Yourself

Try the variable declaration example and tweak the values.