JavaScript & TypeScriptМодуль 6: ООП и паттерны
Контекст this
Как определяется this в JavaScript
Цель урока
В этом уроке ты научишься:
- Понимать, что такое
this - Определять значение
thisв разных ситуациях - Управлять контекстом с помощью
bind,call,apply
Что такое this
this — ссылка на объект, в контексте которого выполняется функция.
let user = {
name: "Иван",
greet() {
console.log("Привет, " + this.name);
}
};
user.greet(); // "Привет, Иван"Правила определения this
1. Метод объекта
let user = {
name: "Иван",
greet() {
console.log(this.name);
}
};
user.greet(); // this = user2. Обычная функция
function showThis() {
console.log(this);
}
showThis(); // window (браузер) или undefined (strict mode)3. Конструктор (new)
function User(name) {
this.name = name;
}
let user = new User("Иван");
console.log(user.name); // "Иван"
// this = новый объект4. Стрелочная функция
let user = {
name: "Иван",
greet: () => {
console.log(this.name); // undefined!
}
};
// Стрелочные функции не имеют своего this
// Они берут this из внешнего окруженияПотеря контекста
let user = {
name: "Иван",
greet() {
console.log("Привет, " + this.name);
}
};
let greet = user.greet;
greet(); // "Привет, undefined" — потеря контекста!
// Решение 1: привязка
let boundGreet = user.greet.bind(user);
boundGreet(); // "Привет, Иван"
// Решение 2: стрелочная функция
setTimeout(() => user.greet(), 1000);bind, call, apply
bind — создаёт новую функцию с привязанным this
let user = { name: "Иван" };
function greet(greeting) {
console.log(greeting + ", " + this.name);
}
let boundGreet = greet.bind(user);
boundGreet("Привет"); // "Привет, Иван"
// С частичным применением
let sayHello = greet.bind(user, "Привет");
sayHello(); // "Привет, Иван"call — вызывает функцию с указанным this
let user = { name: "Иван" };
function greet(greeting, punctuation) {
console.log(greeting + ", " + this.name + punctuation);
}
greet.call(user, "Привет", "!"); // "Привет, Иван!"apply — как call, но аргументы массивом
let user = { name: "Иван" };
function greet(greeting, punctuation) {
console.log(greeting + ", " + this.name + punctuation);
}
greet.apply(user, ["Привет", "!"]); // "Привет, Иван!"Стрелочные функции и this
let user = {
name: "Иван",
friends: ["Мария", "Пётр"],
showFriends() {
// Стрелочная функция берёт this из showFriends
this.friends.forEach(friend => {
console.log(this.name + " дружит с " + friend);
});
}
};
user.showFriends();
// "Иван дружит с Мария"
// "Иван дружит с Пётр"Практика
Задание 1: Определи this
Задача: Что выведет код?
Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
Объект
Задание 2: bind
Задача: Привяжи контекст к функции.
Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
5
Задание 3: Стрелочная функция
Задача: Исправь потерю контекста.
Loading...
Ваш вывод:
Проверь себя
- Что такое
this? - Чем
bindотличается отcall? - Почему стрелочные функции не имеют своего
this?