Utracona referencja this w JavaScript

Załóżmy, że mamy funkcję wewnątrz funkcji. Nazwijmy funkcję zewnętrzną parent, a wewnętrzną - child:

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

Z poprzednich lekcji wiesz, że jeśli zdefiniujesz jakąś zmienną w funkcji zewnętrznej - będzie ona dostępna w funkcji wewnętrznej:

javascriptfunction parent() {
  let str = 'abcde';
  
  function child() {
    console.log(str); // wypisze 'abcde'
  }
  child(); // wywołujemy funkcję wewnętrzną
}

parent(); // wywołujemy funkcję zewnętrzną

Istnieje jednak niuans: funkcja wewnętrzna ma dostęp do wszystkich zmiennych funkcji zewnętrznej, ale nie ma dostępu do this. To znaczy: jeśli funkcja zewnętrzna jest powiązana z jakimś elementem DOM, to this w niej będzie wskazywać na ten element, ale this funkcji wewnętrznej - nie będzie!

Na co w takim razie będzie wskazywać this funkcji wewnętrznej? Odpowiedź: będzie równy undefined (w trybie ścisłym), ponieważ funkcja nie jest z niczym powiązana.

Sprawdźmy to w praktyce. Załóżmy, że mamy daną pole input:

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

Powiążmy z tym inputem funkcję parent, która będzie wywoływana po utracie fokusu przez input:

javascript"use strict";

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

// Wywoła się po utracie fokusu:
function parent() {
  // tutaj będzie jakiś kod
  
  function child() {
    // tutaj będzie jakiś kod
  }
  child(); // wywołujemy funkcję potomną
}

Wypiszmy zawartość this do konsoli w dwóch miejscach: wewnątrz funkcji parent i wewnątrz funkcji child:

javascript"use strict";

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

function parent() {
  console.log(this); // wypisze referencję do naszego inputa
  
  function child() {
    console.log(this); // wypisze undefined
  }
  child();
}

Uruchom ten kod, spraw by input stracił fokus i spójrz do konsoli - zobaczysz, że pierwszy console.log wypisze do konsoli referencję do naszego inputa, a drugi - po prostu undefined. Taka sytuacja, gdy this w nieoczekiwany dla nas sposób wskazuje nie na to, czego potrzebujemy, nazywa się utratą kontekstu.

Задание 1

Załóżmy teraz, że w jednej i w drugiej funkcji będziemy wypisywać value inputa. Określ, co zostanie wypisane w linijkach kodu oznaczonych komentarzami:

javascript"use strict";

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

function parent() {
  console.log(this.value); // co wypisze?
  
  function child() {
    console.log(this.value); // co wypisze?
  }
  child();
}