Modern JS Cheatsheet / Памятка по современному JavaScript: Оператор расширения "..."

Английский оригинал Перевод на русский

Сожалеем, но текст оригинала доступен только зарегистрированным пользователям.

### Оператор расширения "..."

wizjer 02.10.17 в 05:33

0

Оператор расширения "...", появившийся в ES2015, предназначен для раскрытия итерируемых объектов (например, массивов) там, где может поместиться несколько элементов таких объектов.

Tomatoknight 02.10.17 в 19:22

0

#### Пример кода
```js
const arr1 = ["a", "b", "c"];
const arr2 = [...arr1, "d", "e", "f"]; // ["a", "b", "c", "d", "e", "f"]
```
```js
function myFunc(x, y, ...params) {
console.log(x);
console.log(y);
console.log(params)
}
myFunc("a", "b", "c", "d", "e", "f")
// "a"
// "b"
// ["c", "d", "e", "f"]
```
```js
const { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
console.log(x); // 1
console.log(y); // 2
console.log(z); // { a: 3, b: 4 }

Tomatoknight 02.10.17 в 19:23

0

const n = { x, y, ...z };
console.log(n); // { x: 1, y: 2, a: 3, b: 4 }
```

Tomatoknight 02.10.17 в 19:23

0

#### Объяснение

Tomatoknight 02.10.17 в 19:23

0

##### В итерируемых объектах (наподобие массивов)

Tomatoknight 02.10.17 в 19:23

0

Если у нас есть два массива:

Tomatoknight 02.10.17 в 19:23

0

```js
const arr1 = ["a", "b", "c"];
const arr2 = [arr1, "d", "e", "f"]; // [["a", "b", "c"], "d", "e", "f"]
```

Tomatoknight 02.10.17 в 19:24

0

Первый элемент массива *arr2* - это массив, потому что *arr1* напрямую вставляется в *arr2*. Но мы хотим, чтобы *arr2* состоял только из букв. Чтобы добиться этого, мы можем *расширить* элементы массива *arr1* в массив *arr2*.

Tomatoknight 02.10.17 в 19:25

0

С использованием оператора расширения

Tomatoknight 02.10.17 в 19:26

0

```js
const arr1 = ["a", "b", "c"];
const arr2 = [...arr1, "d", "e", "f"]; // ["a", "b", "c", "d", "e", "f"]
```

Tomatoknight 02.10.17 в 19:26

0

Оставшиеся параметры функции

Tomatoknight 02.10.17 в 19:26

0

##### Мы можем использовать оператор оставшихся параметров функции, чтобы вставить параметры в массив, элементы которого можно перебрать при помощи цикла. К каждой функции уже привязан объект **arguments** - это массив, состоящий из всех параметров, переданных функции.

Tomatoknight 02.10.17 в 19:30

0

```js
function myFunc() {
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
myFunc("Коля", "Андреев", 10, 12, 6);
// "Коля"
// "Андреев"
// 10
// 12
// 6
```

Tomatoknight 02.10.17 в 19:31

0

Но давайте представим, что мы хотим, чтобы наша функция создала нового студента, у которого будут отдельные оценки и средний балл. Удобнее будет записать первые два параметра в две отдельные переменные, а все оценки поместить в массив, который можно перебирать.

Tomatoknight 02.10.17 в 19:34

0

Именно это позволяет нам сделать оператор оставшихся параметров!

Tomatoknight 02.10.17 в 19:35

0

```js
function createStudent(firstName, lastName, ...grades) {
// firstName = "Коля"
// lastName = "Андреев"
// [10, 12, 6] -- оператор "..." берет все остальные параметры, переданные функции, и создает переменную "grades" с массивом, в котором они хранятся.

Tomatoknight 02.10.17 в 19:36

0

const avgGrade = grades.reduce((acc, curr) => acc + curr, 0) / grades.length; // Высчитывает из всех оценок средний балл

Tomatoknight 02.10.17 в 19:36

0

return {
firstName: firstName,
lastName: lastName,
grades: grades,
avgGrade: avgGrade
}
}

Tomatoknight 02.10.17 в 19:36

0

const student = createStudent("Коля", "Андреев", 10, 12, 6);
console.log(student);
// {
// firstName: "Коля",
// lastName: "Андреев",
// grades: [10, 12, 6],
// avgGrade: 9,33
// }
```

Tomatoknight 02.10.17 в 19:37

0

> **Примечание:** createStudent - плохая функция, потому что мы не проверяем, существует ли grades.length и отличается ли от 0. Но так функцию легче прочитать, поэтому я этот случай не рассматриваю.

Tomatoknight 02.10.17 в 19:38

0

##### Расширение свойств объектов

Tomatoknight 02.10.17 в 19:38

0

Чтобы понять эту часть, рекомендую прочитать предыдущие объяснения о применении оператора оставшихся параметров к функциям и итерируемым объектам.

Tomatoknight 02.10.17 в 19:39

0

```js
const myObj = { x: 1, y: 2, a: 3, b: 4 };
const { x, y, ...z } = myObj; // деструктуризация объекта
console.log(x); // 1
console.log(y); // 2
console.log(z); // { a: 3, b: 4 }

Tomatoknight 02.10.17 в 19:40

0

// z - это остаток деструктурированного объекта: myObj минус деструктурированные свойства х и у.

Tomatoknight 02.10.17 в 19:41

0

const n = { x, y, ...z };
console.log(n); // { x: 1, y: 2, a: 3, b: 4 }

Tomatoknight 02.10.17 в 19:41

0

// Здесь свойства объекта z расширяются в n

Tomatoknight 02.10.17 в 19:41

0

#### Внешние ресурсы

Tomatoknight 02.10.17 в 19:41

0

- [TC39 - Объекты, расширение и оставшиеся параметры](https://github.com/tc39/proposal-object-rest-spread)
- [Введение в оператор расширения - WesBos](https://github.com/wesbos/es6-articles/blob/master/28%20-%20Spread%20Operator%20Introduction.md)
- [JavaScript и оператор расширения](https://codeburst.io/javascript-the-spread-operator-a867a71668ca)
- [6 отличных примеров использования оператора расширения](https://davidwalsh.name/spread-operator)

Tomatoknight 02.10.17 в 19:42

0
Минутку...