javascript

examples

examples.js
/**
 * =====================================================
 * 5.4 PARAMETERS AND ARGUMENTS - EXAMPLES
 * =====================================================
 * Flexible function parameters
 */

// =====================================================
// 1. PARAMETERS VS ARGUMENTS
// =====================================================

console.log('--- Parameters vs Arguments ---');

// 'a' and 'b' are PARAMETERS
function add(a, b) {
  return a + b;
}

// 5 and 3 are ARGUMENTS
console.log('add(5, 3):', add(5, 3));

// Extra arguments are ignored
console.log('add(5, 3, 10):', add(5, 3, 10));

// Missing arguments become undefined
console.log('add(5):', add(5)); // 5 + undefined = NaN

// =====================================================
// 2. DEFAULT PARAMETERS
// =====================================================

console.log('\n--- Default Parameters ---');

function greet(name = 'Guest', greeting = 'Hello') {
  return `${greeting}, ${name}!`;
}

console.log(greet());
console.log(greet('Alice'));
console.log(greet('Bob', 'Hi'));
console.log(greet(undefined, 'Hey'));

// Default vs null
function example(value = 'default') {
  return value;
}

console.log('\nDefault vs null:');
console.log('No arg:', example());
console.log('undefined:', example(undefined));
console.log('null:', example(null)); // null is passed, not default

// =====================================================
// 3. EXPRESSIONS AS DEFAULTS
// =====================================================

console.log('\n--- Expressions as Defaults ---');

function generateId(id = Math.random().toString(36).substr(2, 9)) {
  return id;
}

console.log('Generated ID:', generateId());
console.log('Generated ID:', generateId());
console.log('Custom ID:', generateId('custom-123'));

// Using earlier parameters
function rectangle(width, height = width) {
  return { width, height, area: width * height };
}

console.log('\nRectangle (5, 10):', rectangle(5, 10));
console.log('Square (5):', rectangle(5));

// =====================================================
// 4. FUNCTION AS DEFAULT
// =====================================================

console.log('\n--- Function as Default ---');

function getTimestamp() {
  console.log('  getTimestamp called');
  return Date.now();
}

function logEvent(message, timestamp = getTimestamp()) {
  return { message, timestamp };
}

console.log('With timestamp:', logEvent('Event', 1234567890));
console.log('Without timestamp:', logEvent('Event'));

// =====================================================
// 5. REST PARAMETERS
// =====================================================

console.log('\n--- Rest Parameters ---');

function sum(...numbers) {
  console.log('Numbers array:', numbers);
  return numbers.reduce((total, n) => total + n, 0);
}

console.log('sum(1, 2, 3):', sum(1, 2, 3));
console.log('sum(1, 2, 3, 4, 5):', sum(1, 2, 3, 4, 5));
console.log('sum():', sum());

// With regular parameters
function logItems(prefix, ...items) {
  console.log(`\n[${prefix}]`);
  items.forEach((item, i) => console.log(`  ${i + 1}. ${item}`));
}

logItems('TODO', 'Buy milk', 'Walk dog', 'Code');

// =====================================================
// 6. ARGUMENTS OBJECT (Legacy)
// =====================================================

console.log('\n--- Arguments Object ---');

function showArgs() {
  console.log('Type:', typeof arguments);
  console.log('Length:', arguments.length);
  console.log('First:', arguments[0]);
  console.log('Is array:', Array.isArray(arguments));

  // Convert to real array
  const argsArray = Array.from(arguments);
  console.log('As array:', argsArray);
}

showArgs(1, 2, 3, 'hello');

// Compare with rest parameters
function showArgsModern(...args) {
  console.log('\nModern rest params:');
  console.log('Is array:', Array.isArray(args));
  console.log('Args:', args);
}

showArgsModern(1, 2, 3, 'hello');

// =====================================================
// 7. SPREAD IN FUNCTION CALLS
// =====================================================

console.log('\n--- Spread in Function Calls ---');

const numbers = [3, 1, 4, 1, 5, 9, 2, 6];

console.log('Max:', Math.max(...numbers));
console.log('Min:', Math.min(...numbers));

// Combining spread
function greetAll(greeting, ...names) {
  return names.map((name) => `${greeting}, ${name}!`);
}

const moreNames = ['Charlie', 'Diana'];
console.log(greetAll('Hello', 'Alice', 'Bob', ...moreNames));

// Spread with other arguments
console.log('\nMixed spread:');
console.log([0, ...numbers, 10]);

// =====================================================
// 8. OBJECT DESTRUCTURING IN PARAMETERS
// =====================================================

console.log('\n--- Object Destructuring ---');

function createUser({ name, age, role = 'user' }) {
  return `${name} (${age}) - ${role}`;
}

console.log(createUser({ name: 'Alice', age: 25 }));
console.log(createUser({ name: 'Bob', age: 30, role: 'admin' }));

// With full default
function greetUser({ name = 'Guest', greeting = 'Hello' } = {}) {
  return `${greeting}, ${name}!`;
}

console.log('\nWith defaults:');
console.log(greetUser());
console.log(greetUser({}));
console.log(greetUser({ name: 'Alice' }));

// Renaming during destructuring
function processData({ id: userId, name: userName }) {
  console.log(`\nProcessing user ${userId}: ${userName}`);
}

processData({ id: 123, name: 'Alice' });

// =====================================================
// 9. ARRAY DESTRUCTURING IN PARAMETERS
// =====================================================

console.log('\n--- Array Destructuring ---');

function processPoint([x, y, z = 0]) {
  return `Point(${x}, ${y}, ${z})`;
}

console.log(processPoint([10, 20]));
console.log(processPoint([10, 20, 30]));

// Swap function
function swap([a, b]) {
  return [b, a];
}

console.log('Swapped:', swap([1, 2]));

// Skip elements
function getExtremes([first, , , last]) {
  return { first, last };
}

console.log('Extremes:', getExtremes([1, 2, 3, 4]));

// =====================================================
// 10. NESTED DESTRUCTURING
// =====================================================

console.log('\n--- Nested Destructuring ---');

function processResponse({
  status,
  data: {
    users,
    metadata: { count },
  },
}) {
  console.log(`Status: ${status}, Users: ${count}`);
  return users;
}

const response = {
  status: 200,
  data: {
    users: ['Alice', 'Bob'],
    metadata: { count: 2, page: 1 },
  },
};

console.log('Users:', processResponse(response));

// =====================================================
// 11. PARAMETER VALIDATION
// =====================================================

console.log('\n--- Parameter Validation ---');

function required(paramName) {
  throw new Error(`'${paramName}' is required`);
}

function createProduct(name = required('name'), price = required('price')) {
  return { name, price };
}

console.log('Valid:', createProduct('Widget', 9.99));

try {
  createProduct('Widget'); // Missing price
} catch (e) {
  console.log('Error:', e.message);
}

// Type validation
function divide(a, b) {
  if (typeof a !== 'number' || typeof b !== 'number') {
    throw new TypeError('Arguments must be numbers');
  }
  if (b === 0) {
    throw new RangeError('Cannot divide by zero');
  }
  return a / b;
}

console.log('\ndivide(10, 2):', divide(10, 2));

// =====================================================
// 12. PASS BY VALUE VS REFERENCE
// =====================================================

console.log('\n--- Pass by Value vs Reference ---');

// Primitives - pass by value
function modifyPrimitive(value) {
  value = 100;
  console.log('Inside function:', value);
}

let num = 50;
modifyPrimitive(num);
console.log('Outside function:', num); // Still 50

// Objects - pass by reference
function modifyObject(obj) {
  obj.modified = true;
}

const user = { name: 'Alice' };
modifyObject(user);
console.log('\nModified object:', user);

// Reassignment doesn't affect original
function reassign(obj) {
  obj = { totally: 'different' };
}

const original = { name: 'Original' };
reassign(original);
console.log('After reassign:', original); // Unchanged

// =====================================================
// 13. AVOIDING MUTATION
// =====================================================

console.log('\n--- Avoiding Mutation ---');

// Bad: mutates original
function addPropertyBad(obj, key, value) {
  obj[key] = value;
  return obj;
}

// Good: returns new object
function addPropertyGood(obj, key, value) {
  return { ...obj, [key]: value };
}

const data = { a: 1 };
const newData = addPropertyGood(data, 'b', 2);

console.log('Original:', data);
console.log('New:', newData);

// =====================================================
// 14. NAMED PARAMETERS PATTERN
// =====================================================

console.log('\n--- Named Parameters Pattern ---');

// Hard to understand
function createUserOld(name, age, active, role, verified) {
  return { name, age, active, role, verified };
}

// Clear and flexible
function createUserNew({
  name,
  age,
  active = true,
  role = 'user',
  verified = false,
}) {
  return { name, age, active, role, verified };
}

console.log('Old way:', createUserOld('Alice', 25, true, 'admin', false));
console.log(
  'New way:',
  createUserNew({
    name: 'Alice',
    age: 25,
    role: 'admin',
  })
);

// =====================================================
// 15. PRACTICAL EXAMPLE: API OPTIONS
// =====================================================

console.log('\n--- Practical: API Options ---');

function fetchData(
  url,
  { method = 'GET', headers = {}, body = null, timeout = 5000, retry = 3 } = {}
) {
  console.log(`${method} ${url}`);
  console.log(`  Timeout: ${timeout}ms, Retries: ${retry}`);
  if (Object.keys(headers).length > 0) {
    console.log('  Headers:', headers);
  }
  if (body) {
    console.log('  Body:', body);
  }
  return { url, method, headers, body, timeout, retry };
}

fetchData('/api/users');
fetchData('/api/users', { method: 'POST', body: { name: 'Alice' } });
fetchData('/api/data', {
  headers: { Authorization: 'Bearer token' },
  timeout: 10000,
});

// =====================================================
// SUMMARY
// =====================================================

console.log('\n--- Summary ---');
console.log(`
Parameters and Arguments:
  • Parameters: Variables in function definition
  • Arguments: Values passed to function
  
Default Parameters:
  • function greet(name = "Guest")
  • undefined triggers default, null doesn't
  • Can use expressions and earlier params

Rest Parameters:
  • function sum(...numbers)
  • Collects remaining args into array
  • Must be last parameter

Spread in Calls:
  • Math.max(...numbers)
  • Expands array into arguments

Destructuring:
  • function f({ name, age }) - Object
  • function f([x, y]) - Array
  • Can have defaults and renaming

Key Points:
  • Primitives: pass by value
  • Objects: pass by reference
  • Avoid mutating arguments
  • Use named parameters for clarity
`);
Examples - JavaScript Tutorial | DeepML