JavaScript Arrays and the spread operator

The spread operator (operator … ) allows you to spread an array into individual values. To do this, an ellipsis is placed in front of the array:

...array

The simplest example:

const users = ["Tom", "Sam", "Bob"];
console.log(...users); // Tom Sam Bob

And by applying this operator, we can populate one array with values ​​from another array:

const users = ["Tom", "Sam", "Bob"];
console.log(users); // ["Tom", "Sam", "Bob"]
const people1 = [...users];
const people2 = new Array(...users);
const people3 = Array.of(...users);
console.log(people1); // ["Tom", "Sam", "Bob"]
console.log(people2); // ["Tom", "Sam", "Bob"]
console.log(people3); // ["Tom", "Sam", "Bob"]

Union of arrays

Using the spread operator, when creating a new array, you can pass the values ​​of several arrays to it at once. For example:

const men = ["Tom", "Sam", "Bob"];
const women = ["Kate", "Alice", "Mary"];
const people = [...men, "Alex", ...women];

console.log(people); // ["Tom", "Sam", "Bob", "Alex", "Kate", "Alice", "Mary"]

In this case, the values ​​from the men, and women arrays are passed to the people array, and, in addition, we can additionally pass individual values ​​that are not included in these arrays.

Passing Function Arguments

Similarly, you can pass values ​​from an array to function parameters:

const people = ["Tom", "Sam", "Bob"];

function print(first, second, third){
    console.log(first);
    console.log(second);
    console.log(third);
}
print(...people); 
// Tom
// Sam
// Bob

In this case, the function print()takes three parameters. An operation …people when calling a function allows you to decompose an array of people into separate values ​​that are passed to the parameters of this function.

It is worth noting that this is not the same as passing an array when calling a function:

print(people);

In this case, the entire array will be passed to the first parameter of the function – the parameter first, and the rest will have a value undefined.

Another example of passing values ​​from an array to parameters:

function sum(a, b, c){
    const d = a + b + c;
    console.log(d);
}
sum(1, 2, 3);
const nums = [4, 5, 6];
sum(...nums);

In the second case, numbers from the nums array are passed to the function. But in order to transfer not just an array, as a single value, but exactly the numbers from this array, the spread operator (ellipsis …) is used.

If the number of function parameters is less than the number of array elements, then the remaining array elements will simply be discarded. If the number of parameters is greater than the number of array elements, then the parameters that have no values ​​will get the value undefined:

const people1 = ["Tom", "Sam", "Bob", "Mike"];
const people2 = ["Alex", "Bill"];
function print(first, second, third){
    console.log(`${first}, ${second}, ${third}`);
}
print(...people1);  // Tom, Sam, Bob
print(...people2);  // Alex, Bill, undefined

Copying arrays

The spread operator provides the easiest way to copy the elements of one array to another. However, caution must be exercised here. Consider an example:

const people = ["Sam", "Tom", "Bob"];
const employees = [...people];
employees[0] = "Dan";
console.log(employees);     // ["Dan", "Tom", "Bob"]
console.log(people);        //  ["Sam", "Tom", "Bob"]

Two arrays are created here. In this case, the elements of the people array are passed to the employees array. Next, we change the first element of the employees array. And from the console output, we can see that changing one array did not affect the other array.

However, what happens if we copy an array of objects:

const people = [{name:"Sam"}, {name:"Tom"}, {name:"Bob"}];
const employees = [...people];
//employees[0] = {name: "Dan"};
employees[0].name = "Dan";
console.log(employees);     //  [{name:"Dan"}, {name:"Tom"}, {name:"Bob"}]
console.log(people);        //  [{name:"Dan"}, {name:"Tom"}, {name:"Bob"}]

Now the people array provides an array of objects, where each object has one property – name. Next, we change the value of the name property on the first element.

And the console output will show us that changing one array led to a change in the second array. Since objects represent a reference type, and when copying to a new array, not a copy of the object is passed (as is the case with strings), but the object itself. Therefore, the first element of one array and the first element of the second array will actually represent the same object.

However, we can completely replace an element of one array with another object, and then the element of the second array will still store a reference to the old object and will not depend on the first array:

const people = [{name:"Sam"}, {name:"Tom"}, {name:"Bob"}];
const employees = [...people];
employees[0] = {name: "Dan"};
console.log(employees); // [{name:"Dan"}, {name:"Tom"}, {name:"Bob"}]
console.log(people); // [{name:"Sam"}, {name:"Tom"}, {name:"Bob"}]

In this case, the first element of the employees array is replaced with a reference to the new object, while the first element of the people array still holds a reference to the old object.