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-ի (strict ռեժիմում), քանի
որ ֆունկցիան ոչ մի բանի հետ կապված չէ:
Եկեք ստուգենք գործնականում: Ենթադրենք ունենք մուտքագրման դաշտ:
<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();
}