Verstehe, wie this dynamisch aufgelöst wird, wie die Prototypenkette funktioniert und was Klassen dem Objektmodell wirklich hinzufügen.
Diese Lektion in Kodokon öffnenDer Wert von this wird an der Aufrufstelle entschieden, nicht bei der Deklaration. Vier Regeln, in absteigender Priorität: der Aufruf mit new, die explizite Bindung (call, apply, bind), der Aufruf als Methode (obj.fn()) und ein einfacher Aufruf (fn()), der im Strict Mode undefined ergibt. Der häufigste Bug aus der Praxis folgt direkt daraus: Das Herauslösen einer Methode aus ihrem Objekt bricht die implizite Bindung.
const user = {
name: "Ada",
greet() {
return "Hello, " + this.name;
},
};
console.log(user.greet()); // "Hello, Ada"
const detached = user.greet;
// detached(); // TypeError: this is undefined
const bound = user.greet.bind(user);
console.log(bound()); // "Hello, Ada"Arrow-Funktionen haben kein eigenes this: Sie fangen es lexikalisch aus dem umgebenden Gültigkeitsbereich ein, genau wie eine Closure. Das macht sie ideal für Callbacks, aber kontraproduktiv als Methoden an Objektliteralen, wo this auf den äußeren Gültigkeitsbereich zeigt. Unter der Haube delegiert jedes Objekt über seine Prototypenkette: Eine fehlende Eigenschaft wird Glied für Glied gesucht, bis null erreicht ist.
function Animal(name) {
this.name = name;
}
Animal.prototype.describe = function () {
return this.name + " is an animal";
};
const dog = new Animal("Rex");
console.log(dog.describe()); // "Rex is an animal"
console.log(Object.getPrototypeOf(dog) ===
Animal.prototype); // true
console.log(dog.hasOwnProperty("describe")); // falseDie class-Syntax ändert dieses Modell nicht: Sie macht es lesbar. Methoden, die im Klassenkörper deklariert werden, landen auf Constructor.prototype und werden daher geteilt. Instanzfelder (einschließlich Arrow-Funktionen, die als Felder zugewiesen werden) werden pro Instanz neu erzeugt: garantierte this-Bindung, aber vervielfachte Speicherkosten. Schließlich bieten #private-Felder eine von der Engine erzwungene Privatsphäre, anders als die _underscore-Konvention.
class BankAccount {
#balance = 0;
deposit(amount) {
if (amount <= 0) throw new Error("Invalid amount");
this.#balance += amount;
return this;
}
get balance() {
return this.#balance;
}
}
const account = new BankAccount();
account.deposit(50).deposit(25);
console.log(account.balance); // 75this im Strict Mode bei einem einfachen Aufruf fn() ohne Objekt und ohne explizite Bindung?this besonders?