Ztráta kontextu v JavaScriptu

Předpokládejme, že máme funkci ve funkci. Pojmenujme vnější funkci parent a vnitřní - child:

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

Z předchozích lekcí víte, že pokud nastavíte nějakou proměnnou ve vnější funkci - bude dostupná ve vnitřní:

javascriptfunction parent() {
  let str = 'abcde';
  
  function child() {
    console.log(str); // vypíše 'abcde'
  }
  child(); // voláme vnitřní funkci
}

parent(); // voláme vnější funkci

Existuje však nuance: vnitřní funkce má přístup ke všem proměnným vnější, ale nemá přístup k this. To znamená: pokud je vnější funkce navázána na nějaký DOM prvek, pak this v ní bude ukazovat na tento prvek, ale this vnitřní funkce - nebude!

Na co tedy bude this vnitřní funkce ukazovat? Odpověď: bude roven undefined (v striktním režimu), protože funkce není na nic navázána.

Ověřme si to v praxi. Předpokládejme, že máme dán input:

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

Navážeme na tento input funkci parent, která se bude volat při ztrátě focusu inputem:

javascript"use strict";

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

// Zavolá se při ztrátě focusu:
function parent() {
  // tady bude nějaký kód
  
  function child() {
    // tady bude nějaký kód
  }
  child(); // voláme dceřinou funkci
}

Vypišme obsah this do konsole na dvou místech: uvnitř funkce parent a uvnitř funkce 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();
}

Spusťte tento kód, ztratťe focus inputu a podívejte se do konsole - uvidíte, že první console.log vypíše do konsole odkaz na náš input, a druhý - prostě undefined. Takovou situaci, kdy this nečekaným způsobem neukazuje na to, co potřebujeme, se nazývá ztráta kontextu.

Задание 1

Předpokládejme nyní, že v jedné i ve druhé funkci budeme vypisovat value inputu. Určete, co se vypíše na řádcích kódu, označených komentáři:

javascript"use strict";

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

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