The rest operator allows a function to take a variable number of arguments and then treat those arguments as an array of arguments:

function product(...numbers) {
  return numbers.reduce(function(acc, number) {
    return acc * number;
  }, 1)
}

console.log(product(2,3,4,5)); 

 

Applied to an array, […] becomes the spread operator and will extract the elements of the array as shown next:

function join(array1, array2) {
  return array1.concat(array2);
}

function join2(array1, array2) {
  return [...array1, ...array2];
}

const colors1 = ['blue', 'red', 'white'];
const colors2 = ['green', 'black', 'purple'];

console.log(join(colors1, colors1));
console.log(join2(colors1, colors1));

// rest and spread
function unshift(array, ...items) {
  return [...items, ...array];
}
console.log(unshift(colors1, 'grey', 'magenta'));