Docs

README

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

  1. •Parameters vs Arguments
  2. •Default Parameters
  3. •Rest Parameters
  4. •The Arguments Object
  5. •Spread in Function Calls
  6. •Destructuring Parameters
  7. •Parameter Validation
  8. •Pass by Value vs Reference
  9. •Named Parameters Pattern
  10. •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

FeatureargumentsRest Parameters
TypeArray-like objectReal Array
Available inRegular functionsAll functions
Arrow functionsNoYes
NamedNoYes
Array methodsNo (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

BenefitDescription
ClarityArguments are self-documenting
Order-independentProperties can be in any order
Optional by defaultCan omit properties with defaults
Easy to extendAdd 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
README - JavaScript Tutorial | DeepML