Parameters: Default, Rest, Destructured & Parameter TDZ
Inputs itne simple nahi — har default naya banta hai, aur TDZ mein panghe mat.
Default parameters apply ONLY when the argument is undefined — not null, not 0, not false! This is the #1 source of confusion.
// 1. Only undefined triggers default
function greet(name, greeting = 'Hello') {
console.log(greeting + ', ' + name + '!');
}
greet('Sai'); // 'Hello, Sai!' (default used)
greet('Sai', 'Namaste'); // 'Namaste, Sai!' (explicit value)
greet('Sai', undefined); // 'Hello, Sai!' (undefined triggers default)
greet('Sai', null); // 'null, Sai!' (null does NOT trigger default!)
// 2. Evaluated at call time — new array each time!
function addToList(item, list = []) {
list.push(item);
return list;
}
console.log(addToList('a')); // ['a']
console.log(addToList('b')); // ['b'] — not ['a', 'b']! New [] each call.
// 3. Can reference earlier parameters
function createProfile(name, age, role = name + ' - ' + age) {
return { name, age, role };
}
console.log(createProfile('Sai', 25));
// { name: 'Sai', age: 25, role: 'Sai - 25' }Parameters have their own scope between the outer scope and the function body. This creates a Temporal Dead Zone (TDZ) for parameters declared after the one being evaluated.
// Parameter TDZ — accessing later param causes ReferenceError
function bad(x = y, y = 2) {
console.log(x, y);
}
// bad(); // ReferenceError: Cannot access 'y' before initialization
// When x's default is evaluated, y is in the TDZ!
function good(x = 1, y = x) {
console.log(x, y);
}
good(); // 1, 1 — x is evaluated first, y can see it
good(5); // 5, 5 — x is 5, y defaults to x (5)
// Function body vars are NOT visible to defaults
function bodyScope(x = outer) {
const outer = 'hello'; // This is in function body, not param scope!
}
// bodyScope(); // ReferenceError: outer is not defined
Rest parameters collect all remaining arguments into a real Array. They replace the old arguments object for modern code.
// Rest parameters — always an Array
function sum(base, ...numbers) {
console.log(Array.isArray(numbers)); // true
return numbers.reduce((acc, n) => acc + n, base);
}
console.log(sum(10, 1, 2, 3)); // 16 (10 + 1 + 2 + 3)
console.log(sum(0)); // 0 (numbers is [])
// Rest vs arguments
function showDifference(...rest) {
console.log('Rest:', rest);
// console.log('Arguments:', arguments); // Avoid in modern code!
}
showDifference('a', 'b', 'c');
// Rest: ['a', 'b', 'c'] — clean array
// Rest with other parameters
function log(level, ...messages) {
messages.forEach(msg => console.log(`[${level}] ${msg}`));
}
log('ERROR', 'File not found', 'Retrying...');
// [ERROR] File not found
// [ERROR] Retrying...You can destructure objects and arrays directly in the parameter list — but there are traps to watch for!
// Destructured object parameter
function createUser({ name, age, role = 'user' }) {
return { name, age, role };
}
console.log(createUser({ name: 'Sai', age: 25 }));
// { name: 'Sai', age: 25, role: 'user' } (inner default)
// Without = {} at end, calling f() throws TypeError!
// createUser(); // TypeError: Cannot destructure property 'name' of undefined
// Safe: outer default provides empty object if no argument
function safeCreateUser({ name = 'Anonymous', age = 0 } = {}) {
return { name, age };
}
console.log(safeCreateUser()); // { name: 'Anonymous', age: 0 }
console.log(safeCreateUser({})); // { name: 'Anonymous', age: 0 }
console.log(safeCreateUser({ name: 'Ali' })); // { name: 'Ali', age: 0 }
// Array destructuring
function getFirstTwo([first, second]) {
return [first, second];
}
console.log(getFirstTwo([10, 20, 30])); // [10, 20]The arguments object behaves differently in strict mode vs sloppy mode — and this trips up many developers.
// Sloppy mode — aliasing
function sloppyAliasing(a, b) {
arguments[0] = 99;
console.log(a); // 99! arguments[0] changed 'a'
console.log(arguments[1]); // 2
}
sloppyAliasing(1, 2);
// Strict mode — no aliasing
function strictAliasing(a, b) {
'use strict';
arguments[0] = 99;
console.log(a); // 1 — 'a' unaffected!
console.log(arguments[0]); // 99 — arguments is a copy
}
strictAliasing(1, 2);
// Converting arguments to real array (old way)
function oldWay() {
const args = Array.prototype.slice.call(arguments);
// Or: const args = [...arguments];
return args.map(x => x * 2);
}
arguments object. Rest gives you a real Array, works in arrow functions, and avoids the aliasing confusion between strict and sloppy mode. The arguments object is a legacy feature kept only for backwards compatibility.Lo kar liya — Key Points:
- ✅ Default parameters apply only when argument is undefined; evaluated at call time so objects/arrays are fresh each call
- ✅ Parameter TDZ: default params can reference earlier params but not later ones (ReferenceError)
- ✅ Rest parameters (...args) collect remaining arguments into a real Array; must be the last parameter
- ✅ Destructured parameters unpack objects/arrays; use = {} outer default to avoid TypeError on no-argument calls
- ✅ In sloppy mode, arguments[i] aliases parameters; in strict mode, they are separate copies
- ✅ Arrow functions have no arguments object; always use rest parameters
Want to track your progress?
Log in to save your place and pick up where you left off.
Progress track karna chahte ho?
Login karo apni progress save karne ke liye aur jahan chhoda tha wahan se shuru karo.
Login