Strata kontextu v JavaScripte

Nech máme funkciu vo funkcii. Povedzme vonkajšiu funkciu nazvime parent, a vnútornú - child:

javascriptfunction parent() {
  function child() {
    
  }
}

Z predchádzajúcich lekcií viete, že ak nastavíte akúkoľvek premennú vo vonkajšej funkcii - bude dostupná vo vnútornej:

javascriptfunction parent() {
  let str = 'abcde';
  
  function child() {
    console.log(str); // vypíše 'abcde'
  }
  child(); // voláme vnútornú funkciu
}

parent(); // voláme vonkajšiu funkciu

Existuje však nuansa: vnútorná funkcia má prístup ku všetkým premenným vonkajšej, ale nemá prístup k this. To znamená: ak je vonkajšia funkcia naviazaná na nejaký DOM element, potom this v nej bude ukazovať na tento element, ale this vnútornej funkcie - nebude!

Na čo potom bude ukazovať this vnútornej funkcie? Odpoveď: bude rovný undefined (v prísnom režime), pretože funkcia nie je na nič naviazaná.

Vyskúšajme to v praxi. Nech máme daný input:

html<input id="elem" value="text">

Naväzme na tento input funkciu parent, ktorá sa bude volať pri strate fokusu inputom:

javascript"use strict";

let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);

// Zavolá sa pri strate fokusu:
function parent() {
  // tu bude nejaký kód
  
  function child() {
    // tu bude nejaký kód
  }
  child(); // voláme dcérsku funkciu
}

Vypíšme obsah this do konzoly na dvoch miestach: vo funkcii parent a vo funkcii child:

javascript"use strict";

let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);

function parent() {
  console.log(this); // vypíše odkaz na náš input
  
  function child() {
    console.log(this); // vypíše undefined
  }
  child();
}

Spustte tento kód, stratte fokus inputu a pozrite sa do konzoly - uvidíte, že prvý console.log vypíše do konzoly odkaz na náš input, a druhý - jednoducho undefined. Takáto situácia, kedy this neočakávaným spôsobom neukazuje na to, čo potrebujeme, sa nazýva strata kontextu.

Задание 1

Nech teraz v jednej aj v druhej funkcii budeme vypisovať value inputu. Určte, čo sa vypíše v riadkoch kódu, označených komentármi:

javascript"use strict";

let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);

function parent() {
  console.log(this.value); // čo vypíše?
  
  function child() {
    console.log(this.value); // čo vypíše?
  }
  child();
}