Javascript – Rest Operator

Javascript REST Parameter or operator (…) is introduced in ES6.

REST Parameters are exactly opposite of spread operator. Spread operator is used to expand all the items of the array while REST parameters is used to condense different items to form an array. REST parameters are also indicated with (…) in javascript.

REST parameters collect all remaining arguments in to an array.

let arr = [1,2,3,4,5,6,7,8]

const [first, second, ...remaining] = arr;
console.log(first); // 1
console.log(second); // 2
console.log(remaining); // [3,4,5,6,7,8]

// or
function myFun(a, b, ...manyMoreArgs) {
	console.log("a", a);
	console.log("b", b);
	console.log("manyMoreArgs", manyMoreArgs);
}

myFun("one", "two", "three", "four", "five", "six");

// a, one
// b, two
// manyMoreArgs, ['three', 'four', 'five', 'six']
JavaScript

The Rest parameters are ideally used with functions instead of arguments object as it has many limitations.

let addAll = (...args) => {
	return args.reduce((a,b) => { return a + b });
}

console.log(addAll(1,2,3,4,5,6,7,8,9,10)); // 55


// or 

function sum(...numbers) {
	return numbers.reduce((acc, num) => acc + num, 0);
}
console.log(sum(1,2,3,4)); // 10

// or

function sum (...theArgs) {
	let total = 0;
	for (const arg of theArgs) {
		total += args;
	}
	return total;
}

console.log(sum(1,2,3)); // 6
JavaScript

Multiply

function multiply(d, ...everything) {
	return everything.map(e => d * e);
}

console.log(multiply(2, 1, 2, 3, 4, 5, 6, 7, 8));
// [2, 4, 6, 8, 10, 12, 14, 16]
JavaScript

Use Cases

  1. Handling variable number of arguments
  2. Replacing arguments Object
  3. Function Overloading Simulation
  4. Currying Functions
  5. Partial Application of Functions
  6. Extending Functionality (Wrapper Functions)
  7. Event Handling in Javascript
  8. Combining with Spread Operator
  9. Default Parameters and Rest Parameters

1. Handling variable number of arguments

When a function can receive any number of arguments, you can use rest parameters to gather all of them in to an array.

function sum(...numbers) {
	return numbers.reduce((total, number) => total + number, 0);
}

console.log(sum(1,2,3,4); // 10
JavaScript

2. Replacing arguments Object

Before rest parameters, the arguments object was used to handle variable arguments, but it’s not an actual array and lacks array methods. Rest parameters provide a better alternative.

function oldWay() {
	console.log(arguments); // Arguments object, not an array
}

function newWay(...args) {
	console.log(args); //proper array
}

oldWay(1,2,3); // [Arguments] { '0': 1, '1': 2, '2': 3}
newWay(1,2,3); // [1, 2, 3]
JavaScript

3. Function Overloading Simulation

While Javascript doesn’t have true function overloading, rest parameters can help simulate it by handling different number or types of arguments.

function displayInfo(name, age, ...otherInfo) {
	console.log(`Name: ${name}, Age: ${age}`);
	console.log(`Other Info:`, otherInfo);
}

displayInfo("John", 30); 
displayInfo("Jane", 25, "Engineer"); // one additional argument
displayInfo("Alice", 40, "Artist", "NYC");  // multiple extra arguments
JavaScript

4. Currying Functions

Rest parameters allow easy currying (breaking a function with multiple arguments into a sequence of single-argument functions).

function curry(f) {
	return function curried(...args) {
		if (args.length >= f.length) {
			return f(...args);
		} else {
			return function(...nextArgs) {
				return curried(...args, ...nextArgs);
			}
		}
	}
}

function sum(a, b, c) {
	return a + b + c;
}

let curriedSum = curry(sum);
console.lgo(curriedSum(1)(2)(3)); // 6
JavaScript

5. Partial application of functions

Rest parameters can be used to implement partial function application, where a function is called with fewer arguments than it expects, returning a new function to take the remaining arguments.

// partial function
function multiply(multiplier, ...numbers) {
	return numbers.map(number => multiplier * number);
}

// new function 
const multiplyBy2 = multiply.bind(null, 2);

console.log(multiplyBy2(1,2,3)); // [2, 4, 6]
JavaScript

6. Extending Functionality (Wrapper Functions)

Rest parameters are useful when creating wrapper functions that extend the functionality of existing functions without altering their signatures.

function logFunctionCalls(fn) {
	return function(...args) {
		console.log(`Calling function with arguments: ${args}`);
		return fn(...args);
	}
}

const add = (a,b) => a + b;
const loggedAdd = logFunctionCalls(add);
console.log(loggedAdd(5,10)); // Calling function with arguments: 5, 10
JavaScript

7. Event Handling in Javascript

Rest parameters are helpful in event handlers, where you may need to pass varying arguments along with event details.

function handleClick(event, ...otherParams) {
	console.log("Event:", event);
	console.log("Other params:", otherParams);
}

document.getElementById("btn").addEventListener("click", event => handleClick(event, "param1", "param2"));
JavaScript

8. Combining with Spread Operator

Rest parameters and the spread operator work well together when passing multiple values between functions or when unpacking values into new structures.

function multiply(factor, ...numbers) {
	return numbers.map(num => num * factor);
}

const result = multiply(2, ...[1,2,3,4]); // spread operator in function call
console.log(result); // [2,4,6,8]
JavaScript

9. Default Parameters and Rest Parameters

Rest parameters can be used alongside default parameters. The default parameters can handle fixed arguments, and the rest can handle additional values.

function buildString(seperator = ",", ...strings) {
	return strings.join(seperator)
}

console.log(buildString(" ", "Hello", "world")); // "Hello world"
console.log(buildString("-", "2024", "09", "06")); // 2024-09-06
JavaScript

In summary, rest parameters offer flexibility in function design, enabling handling variable argument lengths, cleaner function overloading and better support for modern Javascript programming patterns.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *