Rest and Spread Operators

javascript Aug 01, 2019

ES6  introduces two new operators for arrays called rest and spread. The rest and spread operators are both denoted with three ellipses or periods before an identifier ( ...array1 ). The rest operator is used to represent an infinite number of arguments as an array.

The spread operator is used to allow an iterable object to be expanded into multiple arguments. To identify which is being used, we must look at the item that the argument is being applied to. If the operator is applied to an iterable object (array, object, and so on),then it is the spread operator. If the operator is applied to function arguments, then it is the rest operator

In JavaScript, something considered iterable if something (generally values or key/value pairs) can be stepped through one at a time. For example, an array is iterable because the items in the array can be stepped through one at a time. Objects are considered iterable because the key/value pairs can be stepped through one at a time.

The rest operator is used to represent an indefinite number of arguments as an array. When the last parameter of a function is prefixed with the three ellipses, it becomes an array. The array elements are supplied by the actual arguments that are passed into the function, excluding the arguments that already have been given a separate name in the formal declaration of the function. An example of rest destructuring is shown in the following code:

function fn( num1, num2, ...args ) {
  // Destructures an indefinite number of function parameters into the
//array args, excluding the first two arguments passed in.
  console.log( num1 );
  console.log( num2 );
  console.log( args );
fn( 1, 2, 3, 4, 5, 6 );
// Expected output
// 1
// 2
// [ 3, 4, 5, 6 ]

Similar to the arguments object of a JavaScript function, the rest operator contains a list of function arguments. However, the rest operator has three distinct differences from the arguments object. As we already know, the arguments object is an array-like object that contains each argument that's passed into the function. The differences are as follows. First, the rest operator contains only the input parameters that have not been given a separate formal declaration in the function expression.

Second, the arguments object is not an instance of an Array object. The rest parameter is an instance of an array, which means that array functions like sort(), map(), and forEach() can be applied to them directly.

Lastly, the arguments object has special functionality that the rest parameter does not have. For example, the caller property exists on the arguments object.

The rest parameter can be destructured similar to how we destructure an array. Instead of putting a single variable name inside before the ellipses, we can replace it with an array of variables we want to fill. The arguments passed into the function will be destructured as expected for an array. This is shown in the following code:

function fn( ...[ n1, n2, n3 ] ) {
  // Destructures an indefinite number of function parameters into the
  // array args, which is destructured into 3 variables
  console.log( n1, n2, n3 );
fn( 1, 2 ); // Expected output: 1, 2, undefined

The spread operator allows an iterable object such as an array or string to be expanded into multiple arguments (for function calls), array elements (for array literals), or key-value pairs (for object expressions). This essentially means that we can expand an array into arguments for creating another array, object, or calling a function. An example of spread syntax is shown in the following code:

function fn( n1, n2, n3 ) {
  console.log( n1, n2, n3 );
const values = [ 1, 2, 3 ];
fn( ...values ); // Expected output: 1, 2, 3

In the preceding example, we created a simple function that takes in three inputs and logs them to the console. We created an array with three values, then called the function using the spread operator to destructure the array of values into three input parameters for the function.

The rest operator can be used in destructuring objects and arrays. When destructuring an array, if we have more array elements than variables, we can use the rest operator to capture, or catch, all of the additional array elements during destructuring. When using the rest operator, it must be the last parameter in the array destructuring or function arguments list. This is shown in the following code:

const [ n1, n2, n3, ...remaining ] = [ 1, 2, 3, 4, 5, 6 ];
console.log( n1 ); // Expected output: 1
console.log( n2 ); // Expected output: 2
console.log( n3 ); // Expected output: 3
console.log( remaining ); // Expected output: [ 4, 5, 6 ]

n the preceding snippet, we destructured the first three array elements into three variables, n1, n2, and n3. We then captured the remaining array elements with the rest operator and destructured them into the variable that remained.

In summary, the rest and spread operators allow iterable entities to be expanded into many arguments. They are denoted with three ellipses before the identifier name. This allows us to capture arrays of arguments in functions or unused items when destructuring entities. When we use the rest and spread operators, they must be the last arguments that are passed into the expression they are being used in.

Neeraj Dana

Experienced Software Engineer with a demonstrated history of working in the information technology and services industry. Skilled in Angular, React, React-Native, Vue js, Machine Learning