Губитак контекста у 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();
}