Docs
5.4-Parameters-Arguments
5.4 Parameters and Arguments
Overview
Parameters and arguments are fundamental concepts in JavaScript functions. Parameters are variables listed in the function definition, while arguments are the actual values passed when the function is called. JavaScript provides flexible ways to handle parameters, including default values, rest parameters, and destructuring.
Table of Contents
- ā¢Parameters vs Arguments
- ā¢Default Parameters
- ā¢Rest Parameters
- ā¢The Arguments Object
- ā¢Spread in Function Calls
- ā¢Destructuring Parameters
- ā¢Parameter Validation
- ā¢Pass by Value vs Reference
- ā¢Named Parameters Pattern
- ā¢Best Practices
Parameters vs Arguments
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Parameters vs Arguments ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā function greet(name, greeting) { ā PARAMETERS ā
ā return greeting + ", " + name; ā
ā } ā
ā ā
ā greet("Alice", "Hello"); ā ARGUMENTS ā
ā ā
ā ⢠Parameters: Variables in the function definition ā
ā ⢠Arguments: Values passed when calling the function ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
Basic Example
// name and age are PARAMETERS
function createUser(name, age) {
return { name, age };
}
// "Alice" and 25 are ARGUMENTS
createUser('Alice', 25);
Extra or Missing Arguments
function greet(name) {
console.log('Hello, ' + name);
}
// Missing argument - parameter is undefined
greet(); // "Hello, undefined"
// Extra arguments - ignored (in regular functions)
greet('Alice', 25); // "Hello, Alice"
Default Parameters
Set fallback values for parameters when no argument is provided.
Basic Default Values
function greet(name = 'Guest', greeting = 'Hello') {
return `${greeting}, ${name}!`;
}
greet(); // "Hello, Guest!"
greet('Alice'); // "Hello, Alice!"
greet('Bob', 'Hi'); // "Hi, Bob!"
greet(undefined, 'Hey'); // "Hey, Guest!"
Default vs null
function example(value = 'default') {
return value;
}
example(); // "default" (no argument)
example(undefined); // "default" (undefined triggers default)
example(null); // null (null is a valid value)
Expressions as Defaults
function createId(id = Math.random()) {
return id;
}
function greetUser(name, date = new Date()) {
return `Hello ${name}, today is ${date.toDateString()}`;
}
function calculate(a, b = a * 2) {
return a + b;
}
console.log(calculate(5)); // 15 (5 + 10)
Functions as Defaults
function getDefaultValue() {
console.log('Getting default...');
return 42;
}
function example(value = getDefaultValue()) {
return value;
}
example(10); // 10 (getDefaultValue not called)
example(); // 42 (getDefaultValue called)
Default Parameters Order
// Required parameters should come before defaults
function createUser(name, role = 'user', active = true) {
return { name, role, active };
}
// Skipping with undefined
createUser('Alice', undefined, false);
// { name: "Alice", role: "user", active: false }
Rest Parameters
Collect remaining arguments into an array using ....
Syntax
function functionName(first, second, ...rest) {
// rest is an array of remaining arguments
}
Basic Examples
function sum(...numbers) {
return numbers.reduce((total, n) => total + n, 0);
}
sum(1, 2); // 3
sum(1, 2, 3, 4, 5); // 15
sum(); // 0
Combining with Regular Parameters
function logMessage(level, ...messages) {
console.log(`[${level.toUpperCase()}]`);
messages.forEach((msg) => console.log(` - ${msg}`));
}
logMessage('info', 'Starting', 'Connecting', 'Ready');
// [INFO]
// - Starting
// - Connecting
// - Ready
Rest Must Be Last
// ā
Correct
function valid(a, b, ...rest) {}
// ā SyntaxError
// function invalid(...rest, a, b) { }
Real-World Examples
// Logging with prefix
function log(prefix, ...args) {
console.log(`[${prefix}]`, ...args);
}
// Mathematical operations
function multiply(multiplier, ...numbers) {
return numbers.map((n) => n * multiplier);
}
console.log(multiply(2, 1, 2, 3)); // [2, 4, 6]
The Arguments Object
A legacy way to access all arguments in regular functions.
Basic Usage
function showArgs() {
console.log(arguments); // Array-like object
console.log(arguments.length); // Number of arguments
console.log(arguments[0]); // First argument
}
showArgs(1, 2, 3); // Arguments(3) [1, 2, 3]
Arguments is Array-like, Not an Array
function example() {
// ā Doesn't work
// arguments.forEach(arg => console.log(arg));
// ā
Convert to array first
const args = Array.from(arguments);
args.forEach((arg) => console.log(arg));
// ā
Or use spread
const args2 = [...arguments];
}
Comparison: arguments vs rest
| Feature | arguments | Rest Parameters |
|---|---|---|
| Type | Array-like object | Real Array |
| Available in | Regular functions | All functions |
| Arrow functions | No | Yes |
| Named | No | Yes |
| Array methods | No (must convert) | Yes |
Prefer Rest Parameters
// ā Old way
function sum() {
return Array.from(arguments).reduce((a, b) => a + b, 0);
}
// ā
Modern way
function sum(...numbers) {
return numbers.reduce((a, b) => a + b, 0);
}
Spread in Function Calls
Use ... to spread an array as individual arguments.
Basic Usage
const numbers = [1, 2, 3, 4, 5];
Math.max(...numbers); // 5
Math.min(...numbers); // 1
Combining Arrays and Values
const middle = [3, 4, 5];
console.log(1, 2, ...middle, 6, 7); // 1 2 3 4 5 6 7
Apply vs Spread
const args = [1, 2, 3];
// Old way with apply
Math.max.apply(null, args);
// New way with spread
Math.max(...args);
Spread with Rest
function myFunction(first, ...rest) {
console.log('First:', first);
console.log('Rest:', rest);
}
const args = [1, 2, 3, 4, 5];
myFunction(...args);
// First: 1
// Rest: [2, 3, 4, 5]
Destructuring Parameters
Extract values from objects or arrays directly in parameters.
Object Destructuring
function greetUser({ name, age }) {
return `Hello ${name}, you are ${age} years old`;
}
const user = { name: 'Alice', age: 25 };
greetUser(user);
// "Hello Alice, you are 25 years old"
With Default Values
function createUser({ name, role = 'user', active = true } = {}) {
return { name, role, active };
}
createUser({ name: 'Alice' });
// { name: "Alice", role: "user", active: true }
createUser({});
// { name: undefined, role: "user", active: true }
createUser(); // The = {} handles undefined
// { name: undefined, role: "user", active: true }
Renaming Properties
function process({ name: userName, id: oderId }) {
console.log(userName, orderId);
}
process({ name: 'Alice', id: 123 });
// Alice 123
Array Destructuring
function processCoordinates([x, y, z = 0]) {
return `Point at (${x}, ${y}, ${z})`;
}
processCoordinates([10, 20]);
// "Point at (10, 20, 0)"
processCoordinates([10, 20, 30]);
// "Point at (10, 20, 30)"
Nested Destructuring
function processResponse({ data: { users, count }, status }) {
console.log(`${count} users, status: ${status}`);
return users;
}
processResponse({
status: 200,
data: {
users: ['Alice', 'Bob'],
count: 2,
},
});
Parameter Validation
Guard Clauses
function divide(a, b) {
if (typeof a !== 'number' || typeof b !== 'number') {
throw new TypeError('Arguments must be numbers');
}
if (b === 0) {
throw new Error('Cannot divide by zero');
}
return a / b;
}
Required Parameters
function required(name) {
throw new Error(`Parameter '${name}' is required`);
}
function createUser(name = required('name'), age = required('age')) {
return { name, age };
}
createUser('Alice', 25); // Works
createUser('Alice'); // Error: Parameter 'age' is required
createUser(); // Error: Parameter 'name' is required
Type Checking
function processUser(user) {
if (!user || typeof user !== 'object') {
throw new TypeError('User must be an object');
}
if (typeof user.name !== 'string') {
throw new TypeError('User name must be a string');
}
if (typeof user.age !== 'number') {
throw new TypeError('User age must be a number');
}
return { ...user, processed: true };
}
Pass by Value vs Reference
Primitives (Pass by Value)
function modify(value) {
value = 100;
console.log('Inside:', value); // 100
}
let num = 50;
modify(num);
console.log('Outside:', num); // 50 (unchanged)
Objects (Pass by Reference)
function modifyObject(obj) {
obj.modified = true;
console.log('Inside:', obj);
}
const user = { name: 'Alice' };
modifyObject(user);
console.log('Outside:', user);
// { name: "Alice", modified: true } (changed!)
Reassigning vs Mutating
// Reassigning doesn't affect original
function reassign(obj) {
obj = { newProperty: true };
return obj;
}
const original = { name: 'Original' };
reassign(original);
console.log(original); // { name: "Original" }
// Mutating affects original
function mutate(obj) {
obj.newProperty = true;
return obj;
}
mutate(original);
console.log(original); // { name: "Original", newProperty: true }
Avoiding Mutation
// Create a copy before modifying
function updateUser(user, updates) {
return { ...user, ...updates };
}
const user = { name: 'Alice', age: 25 };
const updated = updateUser(user, { age: 26 });
console.log(user); // { name: "Alice", age: 25 } (unchanged)
console.log(updated); // { name: "Alice", age: 26 }
Named Parameters Pattern
Use object destructuring for clearer function calls.
The Problem
// What do these arguments mean?
createUser('Alice', 25, true, false, 'admin');
The Solution
function createUser({
name,
age,
active = true,
verified = false,
role = 'user',
}) {
return { name, age, active, verified, role };
}
// Clear and readable
createUser({
name: 'Alice',
age: 25,
role: 'admin',
});
Benefits
| Benefit | Description |
|---|---|
| Clarity | Arguments are self-documenting |
| Order-independent | Properties can be in any order |
| Optional by default | Can omit properties with defaults |
| Easy to extend | Add new properties without breaking calls |
Combining with Positional Parameters
function fetchData(
url,
{ method = 'GET', headers = {}, body = null, timeout = 5000 } = {}
) {
// url is required and positional
// options are named and optional
console.log(`${method} ${url}`);
return { url, method, headers, body, timeout };
}
fetchData('/api/users');
fetchData('/api/users', { method: 'POST', body: '{}' });
Best Practices
1. Limit Number of Parameters
// ā Too many parameters
function createUser(name, age, email, address, phone, role, active) {}
// ā
Use an options object
function createUser(options) {
const { name, age, email, address, phone, role, active } = options;
}
// ā
Or destructure in parameters
function createUser({ name, age, email, address, phone, role, active }) {}
2. Put Required Parameters First
// ā
Required before optional
function sendEmail(to, subject, { cc, bcc, html } = {}) {}
3. Use Default Parameters Instead of Checks
// ā Manual default checking
function greet(name) {
name = name || 'Guest';
return 'Hello, ' + name;
}
// ā
Default parameter
function greet(name = 'Guest') {
return 'Hello, ' + name;
}
4. Validate Required Parameters
function fetchData(url) {
if (!url) {
throw new Error('URL is required');
}
// ...
}
5. Don't Mutate Arguments
// ā Mutates original
function addTimestamp(data) {
data.timestamp = Date.now();
return data;
}
// ā
Returns new object
function addTimestamp(data) {
return {
...data,
timestamp: Date.now(),
};
}
6. Use Rest Parameters Over Arguments
// ā Using arguments object
function sum() {
return Array.from(arguments).reduce((a, b) => a + b, 0);
}
// ā
Using rest parameters
function sum(...numbers) {
return numbers.reduce((a, b) => a + b, 0);
}
Summary
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Parameters and Arguments Quick Reference ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā // Default parameters ā
ā function greet(name = "Guest") { } ā
ā ā
ā // Rest parameters ā
ā function sum(...numbers) { } ā
ā ā
ā // Spread in calls ā
ā Math.max(...numbers) ā
ā ā
ā // Object destructuring ā
ā function greet({ name, age }) { } ā
ā ā
ā // Array destructuring ā
ā function process([first, second]) { } ā
ā ā
ā // Named parameters pattern ā
ā function create({ name, age, role = "user" }) { } ā
ā ā
ā Key Points: ā
ā ⢠Parameters: Variables in function definition ā
ā ⢠Arguments: Values passed to function ā
ā ⢠undefined triggers default, null doesn't ā
ā ⢠Rest must be last parameter ā
ā ⢠Prefer rest over arguments object ā
ā ⢠Primitives: pass by value ā
ā ⢠Objects: pass by reference ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
Next Steps
- ā¢Practice with the examples in
examples.js - ā¢Complete the exercises in
exercises.js - ā¢Learn about function binding with call, apply, bind
- ā¢Explore closures and scope in depth