Оператор spread
Оператор spread
позволяет разложить массив на отдельные значения. Для этого перед массивом ставится многоточие, простейший пример:
const users = ["Tom", "Sam", "Bob"];
// Tom Sam Bob
console.log(...users);
Применяя этот оператор, мы можем наполнить один массив значениями из другого массива:
const users = ["Tom", "Sam", "Bob"];
// ["Tom", "Sam", "Bob"]
console.log(users);
const people1 = [...users];
const people2 = new Array(...users);
const people3 = Array.of(...users);
// ["Tom", "Sam", "Bob"]
console.log(people1);
// ["Tom", "Sam", "Bob"]
console.log(people2);
// ["Tom", "Sam", "Bob"]
console.log(people3);
Объединение массивов
С помощью оператора spread можно при создания нового массива передать ему значения сразу нескольких массивов:
const men = ["Tom", "Sam", "Bob"];
const women = ["Kate", "Alice", "Mary"];
const people = [...men, "Alex", ...women];
// ["Tom", "Sam", "Bob", "Alex", "Kate", "Alice", "Mary"]
console.log(people);
В данном случае в массив people
передаются значения из массивов men
, women
, кроме того мы можем дополнительно передать отдельные значения, которые не входят в эти массивы.
Передача аргументов функции
Подобным образом можно передавать из массива значения параметрам функции:
const people = ["Tom", "Sam", "Bob"];
function print(first, second, third){
console.log(first);
console.log(second);
console.log(third);
}
print(...people);
// Tom
// Sam
// Bob
В данном случае функция print()
принимает три параметра. Операция ...people
при вызове функции позволяет разложить массив people
на отдельные значения, которые передаются параметрам этой функции.
Стоит отметить, что это не то же самое, что передать при вызове функции массив:
print(people);
В этом случае весь массив будет передан первому параметру функции - параметру first
, а остальные будут иметь значение undefined
.
Еще один пример передачи параметрам значений из массива:
function sum(a, b, c){
const d = a + b + c;
console.log(d);
}
sum(1, 2, 3);
const nums = [4, 5, 6];
sum(...nums);
Во втором случае в функцию передается числа из массива nums
. Но чтобы передавался не просто массив, как одно значение, а именно числа из этого массива, применяется оператор spread
(многоточие ...
).
Если количество параметров функции меньше количества элементов массива, то оставшие элементы массива просто будут отброшены. Если количество параметров больше количества элементов массива, то параметры, которым не досталось значений, получат значение undefined
:
const people1 = ["Tom", "Sam", "Bob", "Mike"];
const people2 = ["Alex", "Bill"];
function print(first, second, third){
console.log(`${first}, ${second}, ${third}`);
}
// Tom, Sam, Bob
print(...people1);
// Alex, Bill, undefined
print(...people2);
Копирование массивов
Оператор spread
предоставляет самый простой способ скопировать элементы одного массива в другой. Однако тут надо соблюдать осторожность. Рассмотрим пример:
const people = ["Sam", "Tom", "Bob"];
const employees = [...people];
employees[0] = "Dan";
// ["Dan", "Tom", "Bob"]
console.log(employees);
// ["Sam", "Tom", "Bob"]
console.log(people);
Здесь создаются два массива. При этом массиву employees передаются элементы массива people
. Далее мы меняем первый элемент массива employees
. И по консольному выводу мы можем увидеть, что изменение одного массива не повлияло на другой массив.
Однако что будет, если мы скопируем массив объектов:
const people = [{name:"Sam"}, {name:"Tom"}, {name:"Bob"}];
const employees = [...people];
//employees[0] = {name: "Dan"};
employees[0].name = "Dan";
// [{name:"Dan"}, {name:"Tom"}, {name:"Bob"}]
console.log(employees);
// [{name:"Dan"}, {name:"Tom"}, {name:"Bob"}]
console.log(people);
Теперь массив people
предоставляет массив объектов, где каждый объект имеет одно свойство - name
. Далее мы изменяем значение свойства name
у первого элемента.
И консольный вывод нам покажет, что изменение одного массива привело к изменению второго массива. Поскольку объекты - представляют ссылочный тип, и при копировании в новый массив передается не копия объекта (как в случае со строками), а сам объект. Поэтому первый элемент одного массива и первый элемент второго массива фактически будет представлять один и тот же объект.
Однако мы можем полностью заменить элемент одного массива на другой объект, и тогда элемент второго массива по прежнему будет хранить ссылку на старый объект и будет не зависеть от первого массива:
const people = [{name:"Sam"}, {name:"Tom"}, {name:"Bob"}];
const employees = [...people];
employees[0] = {name: "Dan"};
// [{name:"Dan"}, {name:"Tom"}, {name:"Bob"}]
console.log(employees);
// [{name:"Sam"}, {name:"Tom"}, {name:"Bob"}]
console.log(people);
В данном случае первый элемент массива employees заменяется на ссылку на новый объект, а первый элемент массива people
по прежнему хранит ссылку на старый объект.