Sobes.tech
Middle

Πώς απαγορεύεται η αλλαγή του πλαισίου σε JavaScript;

sobes.tech AI

Απάντηση από AI

Στην JavaScript, το πλαίσιο εκτέλεσης μιας συνάρτησης (η τιμή του this) καθορίζεται δυναμικά τη στιγμή της κλήσης. Δεν είναι δυνατόν να αποτρέψουμε πλήρως την αλλαγή του με απόλυτη έννοια, αλλά μπορούμε να ελέγξουμε ή να σταθεροποιήσουμε το πλαίσιο με διάφορους τρόπους:

  1. Μέθοδοι call, apply, bind:

    • Το call και το apply επιτρέπουν την κλήση μιας συνάρτησης με ρητά καθορισμένο πλαίσιο και επιχειρήματα (call με διαχωρισμένα, apply με πίνακα).
    • Το bind δημιουργεί μια νέα δεμένη συνάρτηση, στην οποία το this είναι σταθερά ορισμένο κατά τη δημιουργία του, ανεξάρτητα από την επόμενη κλήση. Αυτός είναι ο πιο αποτελεσματικός τρόπος να "απαγορεύσουμε" την αλλαγή πλαισίου για μελλοντικές κλήσεις.
    // Παράδειγμα με bind
    const obj = { value: 42 };
    function showValue() {
      console.log(this.value);
    }
    
    const boundShowValue = showValue.bind(obj);
    
    boundShowValue(); // Θα εμφανίσει 42
    boundShowValue.call({ value: 100 }); // Θα εξακολουθήσει να εμφανίζει 42, το πλαίσιο είναι σταθερό
    
  2. Βέλη (Arrow Functions):

    • Οι βέλεις συναρτήσεις δεν έχουν δικό τους this. Συλλέγουν το this από το περιβάλλον (λεξικογραφικό) κατά τον ορισμό τους.
    • Το πλαίσιο μιας βέλους δεν μπορεί να αλλάξει με call, apply, ή bind.
    // Παράδειγμα με βέλος
    const outerObj = { name: 'Outer' };
    
    class MyClass {
      constructor() {
        this.className = 'MyClass';
        this.showNameArrow = () => {
          // το `this` εδώ συλλέγεται από τον constructor ή το περιβάλλον ορισμού
          console.log(this.className);
        };
      }
    
      showNameRegular() {
        // το `this` εδώ καθορίζεται κατά την κλήση
        console.log(this.className);
      }
    }
    
    const instance = new MyClass();
    instance.showNameArrow(); // Θα εμφανίσει 'MyClass'
    
    const anotherObj = { className: 'Another' };
    const boundArrow = instance.showNameArrow.bind(anotherObj); // Προσπάθεια αλλαγής πλαισίου
    boundArrow(); // Θα εμφανίσει ακόμα 'MyClass', το πλαίσιο της βέλους είναι αμετάβλητο
    
    instance.showNameRegular.call(anotherObj); // Θα εμφανίσει 'Another', το πλαίσιο της κανονικής συνάρτησης αλλάζει
    

Εν κατακλείδι, η "απαγόρευση αλλαγής πλαισίου" είναι καλύτερα να κατανοείται ως αυστηρή σταθεροποίηση του πλαισίου. Για αυτό χρησιμοποιούνται bind για τις κανονικές συναρτήσεις και η φυσική λεξικογραφική σύνδεση για τις βέλεις. Οι βέλεις συναρτήσεις σε αυτό το πλαίσιο είναι πιο "αμετάβλητες".