1. var — “The old-school way”

Scope:

  • Function-scoped
    • var is function-scoped, meaning the variable is accessible throughout the entire function in which it is declared (even before the declaration, due to hoisting). If declared outside of any function, it’s globally scoped.
    • Not limited by { } blocks like if, for, or while.
function test() {
  if (true) {
    var x = 10;
  }
  console.log(x); // ✅ 10 — still accessible!
}

Redeclaration:

  • Allowed in the same scope.
var a = 1;
var a = 2; // ✅ No error

Reassignment:

  • Allowed.
var a = 1;
a = 2; // ✅ Works fine

🔷 Hoisting:

  • Yes, variables are hoisted to the top of their function.
  • Initialized as undefined during hoisting.
  • Script not stopped and it execute continue.
function test() {
  console.log(a); // ✅ undefined
  var a = 5;
}

2. let — “Modern and safer”

🔷 Scope:

  • Block-scoped
    • Only accessible inside the { } block it’s declared in.
if (true) {
  let x = 10;
}
console.log(x); // ❌ ReferenceError
Output:
10
Uncaught ReferenceError: a is not defined

Hoisting:

  • Yes, hoisted to the top of the block.
  • ❗But not initialized — accessing it before declaration causes a ReferenceError.
  • And below code is not executable.
console.log(a); // ❌ ReferenceError
let a = 5;
console.log("I am not executed.");
Output:
Uncaught ReferenceError: a is not defined

Redeclaration:

  • Not allowed in the same scope.
  • SyntaxError will show at line 2 and below code is not executable.
let a = 1;
let a = 2; // ❌ SyntaxError
console.log(a); // I am not executable due to above SyntaxError
Output:
Uncaught ReferenceError: a is not defined

Reassignment:

  • Allowed.
let a = 1;
a = 2; // ✅ Works fine
console.log(a);


Output:
2

3. const — “Constant value”

🔷 Scope:

  • Block-scoped
    • Just like let.
if (true) {
  const x = 10;
}
console.log(x); // ❌ ReferenceError
Output:
10
Uncaught ReferenceError: a is not defined

Hoisting:

  • Yes, but not initialized.
  • ❗Accessing before declaration causes a ReferenceError.
  • And below code is not executable.
console.log(a); // ❌ ReferenceError
const a = 5;
console.log("I am not executable.");
Output:
Uncaught ReferenceError: a is not defined

Redeclaration:

  • Not allowed in the same scope.
  • SyntaxError will show at line 2 and below code is not executable.
const a = 1;
const a = 2; // ❌ SyntaxError
console.log(a); // I am not executable due to above SyntaxError
Output:
Uncaught ReferenceError: a is not defined

Reassignment:

  • Not allowed.
  • Must be initialized immediately, and value cannot be changed.
const a = 1;
a = 2; // ❌ TypeError
console.log(a); // I am not executable due to above TypeError
console.log("I am also not executable line due to above TypeError");
Output:
Uncaught TypeError: Assignment to constant variable.

✅ Exception:

  • If const holds an object or array, the contents can be changed.
const obj = { a: 1 };
obj.a = 2; // ✅ Allowed — only the reference is constant



Quick Comparison Table

Feature var let const
Global Scope
Functional Scope
Block Scope
Can be re-assigned
Can be re-decleared
Hoisted? Yes (with undefined) Yes (but no init) Yes (but no init)

✅ Mini Quiz

Q1: What will be the output?

console.log(a);
var a = 10;

Ans: undefined — because var is hoisted and initialized as undefined.

Q2: What will this do?

console.log(b);
let b = 10;

Ans: ❌ ReferenceError — due to the Temporal Dead Zone for let.

Q3: Can this work?

const c = 5;
c = 6;

Ans: ❌ TypeErrorconst cannot be reassigned.

Q4: What happens here?

const obj = { name: "John" };
obj.name = "Jane";

Ans: ✅ Allowed — const only prevents reassigning the reference, not object properties.

Q5: Will this throw an error?

let x = 1;
let x = 2;

Ans: ❌ SyntaxError — you can’t re-declare a let variable in the same scope.