Решение проблемы с контекстом в JavaScript

В предыдущем уроке вы увидели, как теряется контекст во внутренней функции. Давайте решим эту проблему. Существует несколько способов решения. Давайте их разберем.

Первое решение проблемы

Решение следующее: во внешней функции запишем 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(); }

Возьмите код из предыдущей задачи и исправьте проблему кода с помощью изученного третьего способа.