Загрузка...

Ключевое слово this

Одна и та же функция ярлыка может сказать имя кружки, потом потерять объект, потом показать имя чашки. Фигурные скобки на месте. Изменился вызов. JavaScript выбирает this в момент вызова, а не пока вы набираете функцию.

После простого вызова метода

Страница методов положила функцию на объект и запустила её как product.tag(). В той форме this был объектом перед точкой. На этом страница остановилась. Здесь функция остаётся, а вызов меняется: снят с объекта, наведён через call, зафиксирован через bind или записан стрелкой.

Пять форм, которыми вызов задаёт this

📊 Метод, голый, call, bind, стрелка

Форма Пример Куда садится this
метод product.tag() объект перед точкой
голый let show = product.tag; show() не тот объект (undefined в строгом режиме)
call product.tag.call(cup) объект, который вы отдаёте call, только на этот запуск
bind product.tag.bind(product) зафиксирован на том объекте для следующих вызовов
стрелка () => this.name внутри другой функции this внешней функции, не объект перед точкой

Назовите вызов, прежде чем читать this. Положить функцию на объект не замораживает this. Решает вызов. bind решает заранее для позднего вызова. Стрелка игнорирует вызов и смотрит на функцию, которая её окружает.

Вызов метода — this это объект перед точкой

javascript
"use strict";
let product = {
name: "Mug",
tag() {
return this.name;
}
};
console.log(product.tag());

Точка по-прежнему называет объект

product.tag() запускает tag и ставит this на product. Консоль печатает Mug. Это правило со страницы методов, оставленное здесь базовой линией. Следующие четыре вызова специально сходят с этой линии.

Голый вызов — объекта больше нет рядом

javascript
"use strict";
let product = {
name: "Mug",
tag() {
if (this == null) {
return "missing";
}
return this.name;
}
};
let show = product.tag;
console.log(show());

Снимите функцию с объекта — кружка уходит вместе с точкой

show и product.tag — одна функция. У show() нет объекта перед точкой, поэтому в строгом режиме this равен undefined. Сторож возвращает missing. Уберите сторожа — this.name бросит ошибку. На этой странице строгий режим, чтобы результат был предсказуем. Нестрогий скрипт может направить голый вызов на глобальный объект.

Направьте this на другой объект через call

javascript
"use strict";
let product = {
name: "Mug",
tag() {
return this.name;
}
};
let cup = { name: "Cup" };
console.log(product.tag.call(cup));

call одалживает функцию одному объекту

product.tag.call(cup) по-прежнему выполняет tag кружки, но на этот запуск this — это cup. Консоль печатает Cup. product.name остаётся Mug. call не приклеивает функцию к cup. apply делает ту же работу, когда лишние аргументы лежат в массиве — этому ярлыку они не нужны.

Зафиксируйте объект через bind

javascript
"use strict";
let product = {
name: "Mug",
tag() {
return this.name;
}
};
let show = product.tag.bind(product);
console.log(show());

bind сохраняет объект для позднего голого вызова

bind возвращает новую функцию. Внутри неё this остаётся product, хотя у show() нет точки. Консоль печатает Mug. Исходный tag не меняется. Берите bind, когда кнопка, таймер или другая функция вызовет метод без объекта впереди.

Стрелка берёт this из внешней функции

javascript
"use strict";
let shelf = {
name: "Shelf",
make() {
let product = {
name: "Mug",
tag: () => this.name
};
return product.tag();
}
};
console.log(shelf.make());

Стрелка не берёт this у точки

product.tag() похож на вызов метода, но tag — стрелка. У стрелки нет своего this. Она берёт this из make, а make шёл как shelf.make(), значит this — это shelf. Консоль печатает Shelf, не Mug. Обычный метод на product напечатал бы Mug. Стрелки были на более ранней странице; здесь только их действие на this.

Подгоните вызов под задачу

Объект стоит перед точкой? Читайте this как этот объект. Сняли функцию и не зафиксировали? Не ждите объект. Другой объект, один запуск? Используйте call. Поздний вызов без точки всё ещё должен видеть кружку? Сначала bind. Написали стрелку? Смотрите наружу, на окружающую функцию, а не на объект перед точкой. Конструктор и класс тоже задают this, им отведена более поздняя страница. Дальше JSON: текст, который описывает данные, а не новое правило для this.

Положите зафиксированный ярлык на страницу

Зафиксируйте tag на кружке через bind, затем вызовите новую функцию без точки. Запишите результат в абзац.

Демо страницы — зафиксированный ярлык

html
<!DOCTYPE html>
<html>
<head>
<title>this-keyword — page</title>
</head>
<body>
<p id="line">…</p>
<script>
"use strict";
let product = {
name: "Mug",
tag() {
return this.name;
}
};
let show = product.tag.bind(product);
let box = document.getElementById("line");
box.textContent = show();
</script>
</body>
</html>

Абзац показывает Mug. У show() нет объекта перед точкой, и строка всё равно называет кружку, потому что bind зафиксировал this. Поменяйте только product.name, обновите страницу — абзац последует. Следующий урок: JSON в JavaScript — текст, который описывает данные, а не новое правило для this.

Шаги практики

  1. Вызовите product.tag() и прочитайте Mug.
  2. Скопируйте функцию в show, вызовите show() в строгом режиме и прочитайте missing.
  3. Вызовите product.tag.call(cup) и прочитайте Cup.
  4. Зафиксируйте tag на product, вызовите новую функцию без точки и прочитайте Mug.
  5. Запустите shelf.make() и прочитайте Shelf, не Mug.
  6. В HTML-демо поменяйте только product.name, обновите и прочитайте абзац.

Частые промахи

  • Считать this замороженным только потому, что функция лежит на объекте
  • Вызывать show() в строгом режиме и всё ещё ждать Mug
  • Думать, что call копирует tag на cup
  • Ждать, что bind перепишет исходный tag, а не вернёт новую функцию
  • Писать стрелку вместо метода и ждать объект перед точкой
  • Читать следующую страницу как ещё одно правило this — JSON это текстовый формат данных

Кратко

  • this выбирает вызов, не скобки
  • object.method() ставит this на объект перед точкой
  • Голый вызов в строгом режиме не направляет this на тот объект
  • call ставит this на переданный объект, только на этот запуск
  • bind возвращает функцию, у которой this остаётся зафиксирован
  • Стрелка берёт this из окружающей функции
  • Зафиксированный вызов может заполнить одну строку страницы
  • Дальше: JSON, текст, который описывает данные

🧠 Проверьте Свои Знания

Готов к Началу

Проверьте Свои Знания

Бросьте себе вызов с помощью этой интерактивной викторины и узнайте, насколько хорошо вы понимаете тему

❓
8
Вопросы
🎯
70%
Для Прохождения
♾️
∞
Время
🔄
∞
Попытки

📝 Инструкции

  • Внимательно прочитайте каждый вопрос
  • Выберите лучший ответ на каждый вопрос
  • Вы можете пересдавать тест столько раз, сколько захотите
  • Ваш прогресс будет показан вверху