В предыдущем уроке вы увидели, как теряется контекст во внутренней функции. Давайте решим эту проблему. Существует несколько способов решения. Давайте их разберем.
Первое решение проблемы
Решение следующее: во внешней функции запишем
this
в любую переменную и эта переменная
будет доступна во внутренней функции, как
и все переменные (обычно эту переменную называют
self
). Таким образом мы передадим
this
из внешней функции во внутреннюю:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this.value); // выведет 'text'
let self = this; // запишем this в любую переменную, например, в self
function child() {
console.log(self.value); // выведет 'text'
}
child();
}
Пусть дан такой код:
<input id="elem" value="3">
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', func);
function func() {
alert( square() );
function square() {
return this.value * this.value;
}
}
Автор кода хотел, чтобы по потери фокуса
на экран вывелся квадрат числа из value
инпута. Однако, почему-то при потери фокуса
в консоль выдается ошибка. Исправьте ошибку
автора кода. Напишите текст, в котором вы
дадите объяснение автору кода, почему возникла
его ошибка.
Второе решение проблемы
Существует и другое решение проблемы. Сделаем
так, чтобы функция child
принимала
параметр:
function child(param) {
// тут будет код
}
А при вызове этой функции будем передавать
в нее this
:
function parent() {
child(this); // передаем параметром this
function child(param) {
// в переменной param лежит переданное содержимое this
}
}
Так как вызов child
осуществляется
в родительской функции, то и передаваемый
this
указывает на то, что нужно. Затем
этот this
попадает в параметр param
и в таком виде и будет доступен внутри функции.
Вот окончательный код:
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
child(this); // передаем параметром this
function child(param) {
console.log(param.value); // выводим value инпута
}
}
Возьмите код из предыдущей задачи и исправьте проблему кода с помощью изученного второго способа.
Третье решение проблемы
Третье решение проблемы заключается в использовании стрелочных функций, которые не так давно появились в JavaScript. Такие функции, помимо всего прочего, не имеют своего контекста, а сохраняют контекст родителя. Исправим нашу проблему с помощью стрелочной функции:
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this.value); // выведет 'text'
let child = () => {
console.log(this.value); // выведет 'text'
}
child();
}
Возьмите код из предыдущей задачи и исправьте проблему кода с помощью изученного третьего способа.