Пусть у нас есть функция в функции. Давайте
внешнюю функцию назовем parent
, а
внутреннюю - child
:
function parent() {
function child() {
}
}
Из предыдущих уроков вы знаете, что если задать какую-либо переменную во внешней функции - она будет доступна во внутренней:
function parent() {
let str = 'abcde';
function child() {
console.log(str); // выведет 'abcde'
}
child(); // вызываем внутреннюю функцию
}
parent(); // вызываем внешнюю функцию
Есть, однако, нюанс: внутренняя функция имеет
доступ ко всем переменным внешней, но не
имеет доступа this
. То есть: если
внешняя функция привязана к какому-то DOM
элементу, то this
в ней будет указывать
на этот элемент, но this
внутренней
функции - не будет!
На что же тогда будет указывать this
внутренней функции? Ответ: он будет равен
undefined
(в строгом режиме), так
как функция ни к чему не привязана.
Давайте проверим на практике. Пусть у нас дан инпут:
<input id="elem" value="text">
Привяжем к этому инпуту функцию parent
,
которая будет вызываться по потери фокуса инпутом:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
// Вызовется по потери фокуса:
function parent() {
// тут будет какой-то код
function child() {
// тут будет какой-то код
}
child(); // вызываем дочернюю функцию
}
Давайте выведем содержимое this
в
консоль в двух местах: внутри функции parent
и внутри функции child
:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this); // выведет ссылку на наш инпут
function child() {
console.log(this); // выведет undefined
}
child();
}
Запустите этот код, потеряйте фокус инпуту
и посмотрите в консоль - вы увидите, что
первый console.log
выведет в консоль
ссылку на наш инпут, а второй - просто undefined
.
Такая ситуация, когда this
неожиданным
для нас образом указывает не на то, что нам
нужно, называется потеря контекста.
Пусть теперь в одной и во второй функции
мы будем выводить value
инпута. Определите,
что выведется в строчках кода, отмеченных
комментариями:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this.value); // что выведет?
function child() {
console.log(this.value); // что выведет?
}
child();
}