Страта кантэксту ў JavaScript
Хай у нас ёсць функцыя ў функцыі. Давайце
знешнюю функцыю назвамем 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();
}