Статистика использования. Отключена, пока вы её не разрешите.
Реклама и измерение рекламы. Отключены, пока вы их не разрешите.
О САЙТЕ
Все открытые вкладки сайта
JavaScript · Синтаксис · Промежуточный
Стрелочные функции и this
10 задач
Освой синтаксис стрелочных функций и пойми как `this` ведёт себя по-разному в стрелочных и обычных функциях — ключевое различие для классов, колбэков и обработчиков событий.
Краткое введение в тему и пояснения перед упражнениями (упражнения ниже):
Стрелочные функции — это компактная альтернатива обычным функциональным выражениям. Разница в синтаксисе простая; разница в поведении `this` — фундаментальная.
**Синтаксис**
```javascript
// Обычное функциональное выражение
const double = function(x) { return x * 2; };
// Стрелочная функция — то же самое
const double = (x) => { return x * 2; };
// Один параметр — скобки необязательны
const double = x => { return x * 2; };
// Одно выражение — фигурные скобки и return необязательны (неявный возврат)
const double = x => x * 2;
// Без параметров — скобки обязательны
const greet = () => "Hello!";
// Возврат литерала объекта — обернуть в скобки чтобы избежать неоднозначности с блоком
const makeUser = name => ({ name: name, active: true });
```
**Как `this` работает в стрелочных функциях**
Обычная функция получает собственный `this` — определяется тем как она вызывается. Стрелочная функция не имеет собственного `this`. Она захватывает `this` из окружающей лексической области в момент определения стрелочной функции, и он никогда не меняется.
```javascript
class Timer {
constructor() {
this.seconds = 0;
}
start() {
// Стрелочная функция: this === экземпляр Timer (лексический this)
setInterval(() => {
this.seconds++;
console.log(this.seconds);
}, 1000);
}
startBroken() {
// Обычная функция: this === undefined (strict) или глобальный объект
setInterval(function() {
this.seconds++; // TypeError или NaN — неправильный this
}, 1000);
}
}
```
**Когда НЕ использовать стрелочные функции**
Стрелочные функции подходят не всегда:
- Методы объекта: `this` в стрелочном методе ссылается на внешнюю область, не на объект.
- Конструкторы: стрелочные функции нельзя вызывать через `new` — они бросают TypeError.
- Объект `arguments`: у стрелочных функций нет собственного `arguments`.
- Динамический `this` (обработчики событий где `this` должен быть элементом): используй обычные функции.
```javascript
const obj = {
value: 42,
getValue: () => this.value, // неправильно — this не является obj
getValueOk() { return this.value; }, // правильно
};
```
Стрелочные функции в методах массива, классах и промисах
Стрелочные функции особенно удобны в трёх контекстах: методы массивов, методы классов с асинхронными колбэками и цепочки промисов. Каждый случай использует лексический `this` или лаконичный синтаксис.
**Методы массивов — самое частое использование**
```javascript
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2); // [2, 4, 6, 8, 10]
const evens = numbers.filter(n => n % 2 === 0); // [2, 4]
const total = numbers.reduce((sum, n) => sum + n, 0); // 15
// Цепочка
const result = numbers
.filter(n => n > 2)
.map(n => n * 10);
// [30, 40, 50]
```
Неявный возврат делает колбэки из одного выражения лаконичными без потери ясности.
**Методы классов с setTimeout / setInterval**
```javascript
class Counter {
constructor() {
this.count = 0;
}
startCounting() {
setInterval(() => {
this.count++;
console.log(this.count);
}, 1000);
}
}
```
Стрелочная функция внутри `setInterval` захватывает `this` из области `startCounting` — то есть из экземпляра класса. Обычная функция потеряла бы `this` при вызове таймером.
**Цепочки промисов**
```javascript
fetch("/api/user")
.then(res => res.json())
.then(data => {
console.log(data.name);
return data;
})
.catch(err => console.error(err));
```
Стрелочные функции делают цепочку читаемой. Каждый колбэк `.then` — однострочник или короткий блок без лишнего ключевого слова `function`.
**Возврат объекта с неявным return**
```javascript
const makePoint = (x, y) => ({ x, y });
makePoint(3, 5); // { x: 3, y: 5 }
```
Оборачивай объект в скобки — иначе `{` воспринимается как начало блока, не объектный литерал, и функция возвращает `undefined`.
Сравнение бок о бок и быстрый справочник по синтаксису.
**Варианты синтаксиса**
```javascript
// Несколько параметров, блочное тело, явный возврат
const add = (a, b) => { return a + b; };
// Несколько параметров, неявный возврат
const add = (a, b) => a + b;
// Один параметр, неявный возврат
const double = x => x * 2;
// Без параметров
const rand = () => Math.random();
// Возврат объектного литерала (обернуть в скобки)
const point = (x, y) => ({ x, y });
```
**Стрелочная vs обычная функция — ключевые отличия**
`this`: Стрелочная — лексический (наследует из окружающей области). Обычная — динамический (определяется местом вызова).
`new`: Стрелочная — запрещено (бросает TypeError). Обычная — разрешено (создаёт экземпляр).
`arguments`: Стрелочная — нет собственного `arguments` (наследует из охватывающей функции). Обычная — имеет собственный объект `arguments`.
`prototype`: Стрелочная — нет свойства `prototype`. Обычная — есть `prototype`.
`super`: Стрелочная — наследует от охватывающего метода. Обычная — каждый метод имеет собственный `super`.
**Когда использовать каждую**
Выбирай стрелочную когда:
- Колбэки для методов массива (map, filter, reduce)
- Колбэки где нужно сохранить `this` из внешней области (setTimeout, setInterval, промисы)
- Короткие встроенные выражения где `function` добавляет шум
Выбирай обычную функцию когда:
- Методы объекта (нужен `this` как объект)
- Конструкторы (вызов через `new`)
- Функции которые используют `arguments`
- Обработчики событий где `this` должен быть целевым элементом
Из массива `products` отфильтруй только товары с `price > 100` и преобразуй каждый только в `name`. Используй стрелочные функции для обеих операций. Выведи результат.
Напиши стрелочную функцию `makeProduct`, принимающую `name` и `price` и возвращающую объект `{ name, price }` с неявным возвратом.
Проверь с `"Laptop"` и `999`.
// твой код здесь
console.log(makeProduct("Laptop", 999));
Класс `Counter` имеет `increment` как обычный метод и `decrement` как стрелочную функцию-свойство. Вызови оба на экземпляре и выведи `count` после каждого.
Понаблюдай какая форма корректно работает после деструктуризации.
class Counter {
count = 0;
increment() {
this.count++;
}
decrement = () => {
this.count--;
};
}
const c = new Counter();
c.increment();
console.log(c.count);
c.decrement();
console.log(c.count);
// Деструктурируй и вызови — какой ломается?
const { increment, decrement } = c;
increment();
console.log(c.count);
decrement();
console.log(c.count);
Завершить цепочку промисов: resolve со значением `42`, затем удвоить в `.then`, затем вывести результат в следующем `.then`. Используй стрелочные функции для обоих колбэков.
const p = new Promise(resolve => {
resolve(42);
});
p
.then(/* удвоить значение */)
.then(/* вывести результат */);
Решение
const p = new Promise(resolve => {
resolve(42);
});
p
.then(val => val * 2)
.then(val => console.log(val));
Мы используем необходимые cookies для работы сайта. С вашего разрешения мы также можем сохранять настройки сайта и использовать аналитические и рекламные cookies, чтобы понимать использование сайта и поддерживать развитие проекта.
* Вы всегда можете изменить свой выбор в настройках сайта.
Выберите категории cookies
Настройки аналитики
Можно отключить аналитику использования платформы. Также можно отправить в Google Analytics запрос на удаление данных об использовании этого сайта, связанных с этим браузером.
Учебный workspace
Учитесь, читая, запуская код и решая задачи.
Практикуйте программирование с пояснениями тем, упражнениями, инструментами browser IDE, проверкой regex и тренировкой печати кода в одном workspace.
Открывайте инструменты во вкладках.Упражнения, IDE-инструменты и тренажеры остаются доступными как вкладки сайта.
Переключайтесь без потери контекста.Переходите между пояснениями, кодом и утилитами, сохраняя свое место.
Используйте sidebar как карту.Левые панели содержат навигацию, настройки, файлы, libraries и управление инструментами.
PythonJavaScriptSQLite
Одна IDE, три практичных режима
Python в браузере.Запускайте небольшие скрипты, пробуйте библиотеки и тренируйте API-запросы без установки.
JavaScript для быстрых экспериментов.Проверяйте код для браузера и сравнивайте идеи рядом с учебными материалами.
SQLite для практики с данными.Открывайте обозреватель базы данных, изучайте таблицы, пишите запросы и учитесь SQL локально.
ТемаIDE
Работайте рядом в split tabs
Держите инструкции перед глазами.Откройте упражнение или справочную страницу рядом с IDE, вместо постоянных переключений.
Сравнивайте инструменты во время обучения.Размещайте проверки regex, пояснения и эксперименты с кодом рядом, когда это нужно для задачи.
Закройте split, когда закончите.Workspace вернётся к одной сфокусированной вкладке, а открытые вкладки сайта останутся доступны.
Тренажер слепой печати кода
Или просто текста
Тренажер рассчитан на физическую клавиатуру.Откройте этот раздел на ноутбуке или компьютере с широким экраном. На телефоне тренировка слепой печати не будет корректной.
Скорость: 0 зн/мин
0 слов/мин
Лучшая скорость (60с): 0 зн/мин
0 слов/мин
Ошибки: 0
Общее время: 0.0 с
Для активации режима слепого набора не подсматривайте на физическую клавиатуру.