Modern JS Cheatsheet / Памятка по современному JavaScript: Стрелочные функции

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

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

### <a name="arrow_func_concept"></a> Стрелочные функции

Tomatoknight 29.09.17 в 15:22

0

В обновлении ES6 JavaScript добавлены *стрелочные функции*, которые являются еще одним способом объявления и использования функций. Вот некоторые их преимущества:

a_popova 02.10.17 в 15:15

0

- краткость;
- *this* берется из окружающего контекста;
- неявный возврат.

Tomatoknight 29.09.17 в 15:26

0

#### Пример кода

Tomatoknight 29.09.17 в 15:26

0

- Краткость и неявный возврат

Tomatoknight 29.09.17 в 15:26

0

```js
function double(x) { return x * 2; } // Обычный способ
console.log(double(2)) // 4
```

Tomatoknight 29.09.17 в 15:27

0

```js
const double = x => x * 2; // Та же функция, записанная в виде стрелочной функции с неявным возвратом
console.log(double(2)) // 4
```

Tomatoknight 29.09.17 в 15:27

0

Связывание с *this*

Tomatoknight 29.09.17 в 15:28

1

- Переменная *this*

a_popova 02.10.17 в 15:16

0

В стрелочной функции *this* равняется значению *this* окружающего контекста исполнения. Со стрелочными функциями вам больше не придется заниматься фокусами вроде "that = this", чтобы объявить функцию внутри функции.

Tomatoknight 29.09.17 в 15:29

0

Внутри стрелочной функции значение *this* равно значению *this* во внешней области видимости. В принципе, со стрелочными функциями вам больше не нужно делать трюк “that = this” перед вызовом функции внутри функции.

a_popova 02.10.17 в 15:17

1

```js
function myFunc() {
this.myVar = 0;
setTimeout(() => {
this.myVar++;
console.log(this.myVar) // 1
}, 0);
}
```

Tomatoknight 29.09.17 в 15:29

0

#### Подробное объяснение

Tomatoknight 29.09.17 в 15:30

0

##### Краткость

Tomatoknight 29.09.17 в 15:30

0

Стрелочные функции по ряду причин короче, чем традиционные. Рассмотрим все возможные случаи:

Tomatoknight 29.09.17 в 15:30

1

Стрелочные функции являются более короткими, чем традиционные во многих случаях. Давайте рассмотрим все возможные случаи:

a_popova 02.10.17 в 15:18

0

- Явный и неявный возврат

Tomatoknight 29.09.17 в 15:30

0

В теле функции с **явным возвратом** используется ключевое слово *return*.

Tomatoknight 29.09.17 в 15:31

0

**Явный возврат** - это функция, в теле которой используется ключевое слово **return**.

a_popova 02.10.17 в 15:18

0
+4

```js
function double(x) {
return x * 2; // эта функция явно возвращает x * 2, использовано ключевое слово *return*
}
```

Tomatoknight 29.09.17 в 15:32

0

При традиционном способе написания функций возврат всегда был явным. Со стрелочными функциями его можно сделать *неявным*. Это значит, что для возврата значения не нужно писать ключевое слово *return*.

Tomatoknight 29.09.17 в 15:33

1

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

a_popova 02.10.17 в 15:19

0

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

Tomatoknight 29.09.17 в 15:36

0

```js
const double = (x) => {
return x * 2; // Явный возврат
}
```

Tomatoknight 29.09.17 в 15:36

0

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

Tomatoknight 29.09.17 в 15:37

0

```js
const double = (x) => x * 2;
```

Tomatoknight 29.09.17 в 15:37

0

Для этого нам просто нужно **убрать фигурные скобки** и ключевое слово **return**. Поэтому это и называется *неявным* возвратом: ключевого слова *return* нет, но функция все равно вернет ```x * 2```.

Tomatoknight 29.09.17 в 15:38

1
+1

> **Примечание**: если ваша функция не возвращает никаких значений (с *побочными эффектами*), то в ней нет ни явного, ни неявного возврата.

Tomatoknight 29.09.17 в 15:43

1

> **Примечание:**: Если ваша функция не возвращает значение (имеет *побочные эффекты*), она не делает ни явного, ни неявного возврата.

a_popova 02.10.17 в 15:20

0

- Только один аргумент

Tomatoknight 29.09.17 в 15:43

0

Если ваша функция принимает только один параметр, можно опустить скобки вокруг него. Если мы снова обратимся к функции *double*:

Tomatoknight 29.09.17 в 15:44

0

Если ваша функция принимает только один параметр, вы можете опустить скобки вокруг него. Если мы вернемся к функции *double* в коде выше:

a_popova 02.10.17 в 15:20

1

```js
const double = (x) => x * 2; // эта стрелочная функция принимает только один параметр
```

Tomatoknight 29.09.17 в 15:44

0

Скобки вокруг единственного параметра можно не писать:

Tomatoknight 29.09.17 в 15:44

0

Скобки вокруг этого параметра могут быть отброшены:

a_popova 02.10.17 в 15:20

0

```js
const double = x => x * 2; // эта стрелочная функция принимает только один параметр
```

Tomatoknight 29.09.17 в 15:45

0

Нет аргументов

Tomatoknight 29.09.17 в 15:45

0

- Без аргументов

a_popova 02.10.17 в 15:21

1

Когда стрелочная функция вообще не принимает никаких аргументов, нужно написать пустые скобки, иначе синтаксис будет неверным.

Tomatoknight 29.09.17 в 15:45

1

Когда у стрелочной функции нет ни одного параметра, вам нужно ставить скобки, иначе это будет неверный синтаксис.

a_popova 02.10.17 в 15:21

0

```js
() => { // Скобки есть, все хорошо
const x = 2;
return x;
}
```

Tomatoknight 29.09.17 в 15:46

0

```js
=> { // Скобок нет, так работать не будет!
const x = 2;
return x;
}
```

Tomatoknight 29.09.17 в 15:46

0

Обращение к *this*

Tomatoknight 29.09.17 в 15:46

0

##### this ссылка

a_popova 02.10.17 в 15:21

0
+3

Чтобы понять этот нюанс, связанный со стрелочными функциями, вам нужно знать, как в JavaScript ведет себя [this](#this_def).

Tomatoknight 29.09.17 в 15:47

0

Чтобы понять эту тонкость, представленную стрелочными функциями, вы должны понимать, как [this](#this_def) ведёт себя в JavaScript.

a_popova 02.10.17 в 15:22

0
+1

В стрелочной функции *this* равняется значению *this* окружающего контекста исполнения. Это значит, что стрелочная функция не создает собственного *this*, а берет его из окружения.

Tomatoknight 29.09.17 в 15:48

0

В стрелочной функции значение *this* равно значению *this* внешнего окружения. Это означает, что стрелочная функция не создает новый *this*, а получает его из окружения.

a_popova 02.10.17 в 15:22

0

Если вы не используете стрелочные функции и хотите получить доступ к переменной из *this* в функции внутри другой функции, вам придется использовать фокус с *that = this* или *self = this*.

Tomatoknight 29.09.17 в 15:49

0

Вот, к примеру, использование функции setTimeout внутри функции myFunc:

Tomatoknight 29.09.17 в 15:49

1

Например, использовать функцию setTimeout внутри myFunc:

a_popova 02.10.17 в 15:23

0
+2

```js
function myFunc() {
this.myVar = 0;
var that = this; // Тот самый фокус *that = this*
setTimeout(
function() { // В этой области видимости функции создается новый *this*
that.myVar++;
console.log(that.myVar) // 1

Tomatoknight 29.09.17 в 15:51

0

console.log(this.myVar) // undefined -- см. объявление функции выше
},
0
);
}
```

Tomatoknight 29.09.17 в 15:52

0

Но в случае стрелочных функций *this* берется из окружения:

Tomatoknight 29.09.17 в 15:52

0

```js
function myFunc() {
this.myVar = 0;
setTimeout(
() => { // this берется из окружения. В данном случае - из myFunc
this.myVar++;
console.log(this.myVar) // 1
},
0
);
}
```

Tomatoknight 29.09.17 в 15:52

0

#### Полезные ресурсы

Tomatoknight 29.09.17 в 15:52

0

- [Введение в стрелочные функции - WesBos](http://wesbos.com/arrow-functions/)
- [Стрелочные функции в JavaScript - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
- [Стрелочные функции и лексическое значение *this*](https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4)

Tomatoknight 29.09.17 в 15:54

0
Минутку...