Απώλεια περιβάλλοντος σε JavaScript

Ας υποθέσουμε ότι έχουμε μια συνάρτηση εντός συνάρτησης. Ας ονομάσουμε την εξωτερική συνάρτηση parent, και την εσωτερική - child:

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

Από προηγούμενα μαθήματα γνωρίζετε ότι εάν ορίσετε οποιαδήποτε μεταβλητή στην εξωτερική συνάρτηση - θα είναι προσβάσιμη στην εσωτερική:

javascriptfunction parent() {
  let str = 'abcde';
  
  function child() {
    console.log(str); // θα τυπώσει 'abcde'
  }
  child(); // καλούμε την εσωτερική συνάρτηση
}

parent(); // καλούμε την εξωτερική συνάρτηση

Υπάρχει, ωστόσο, μια απόχρωση: η εσωτερική συνάρτηση έχει πρόσβαση σε όλες τις μεταβλητές της εξωτερικής, αλλά δεν έχει πρόσβαση στο this. Δηλαδή: εάν η εξωτερική συνάρτηση είναι δεσμευμένη σε κάποιο DOM στοιχείο, τότε το this σε αυτήν θα δείχνει σε αυτό το στοιχείο, αλλά το this της εσωτερικής συνάρτησης - δεν θα δείχνει!

Σε τι θα δείχνει τότε το this της εσωτερικής συνάρτησης; Απάντηση: θα είναι ίσο με undefined (σε αυστηρή λειτουργία), αφού η συνάρτηση δεν είναι δεσμευμένη σε τίποτα.

Ας το δοκιμάσουμε στην πράξη. Ας υποθέσουμε ότι μας δίνεται ένα πεδίο εισόδου:

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

Ας δεσμεύσουμε σε αυτό το πεδίο εισόδου τη συνάρτηση parent, η οποία θα καλείται όταν το πεδίο εισόδου χάσει την εστίαση:

javascript"use strict";

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

// Θα κληθεί όταν χαθεί η εστίαση:
function parent() {
  // εδώ θα υπάρχει κάποιος κώδικας
  
  function child() {
    // εδώ θα υπάρχει κάποιος κώδικας
  }
  child(); // καλούμε την θυγατρική συνάρτηση
}

Ας τυπώσουμε το περιεχόμενο του this στην κονσόλα σε δύο σημεία: μέσα στη συνάρτηση parent και μέσα στη συνάρτηση child:

javascript"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 με απροσδόκητο τρόπο δεν δείχνει σε αυτό που χρειαζόμαστε, ονομάζεται απώλεια περιβάλλοντος.

Задание 1

Ας υποθέσουμε τώρα ότι και στις δύο συναρτήσεις θα τυπώνουμε το value του πεδίου εισόδου. Προσδιορίστε, τι θα τυπωθεί στις γραμμές κώδικα, που σημειώνονται με σχόλια:

javascript"use strict";

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

function parent() {
  console.log(this.value); // τι θα τυπώσει;
  
  function child() {
    console.log(this.value); // τι θα τυπώσει;
  }
  child();
}