Comprende cómo se resuelve this de forma dinámica, cómo funciona la cadena de prototipos y qué añaden realmente las clases al modelo de objetos.
Abrir esta lección en KodokonEl valor de this se decide en el punto de llamada, no en el momento de la declaración. Cuatro reglas, en orden decreciente de prioridad: llamar con new, enlace explícito (call, apply, bind), llamar como método (obj.fn()) y una llamada simple (fn()), que produce undefined en modo estricto. El bug más común del mundo real se deriva directamente: extraer un método de su objeto rompe el enlace implícito.
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"Las funciones flecha no tienen su propio this: lo capturan léxicamente del ámbito que las envuelve, igual que una closure. Eso las hace ideales para los callbacks, pero contraproducentes como métodos en objetos literales, donde this apuntará al ámbito exterior. Bajo el capó, cada objeto delega a través de su cadena de prototipos: una propiedad ausente se busca eslabón por eslabón hasta alcanzar null.
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")); // falseLa sintaxis class no cambia este modelo: lo hace legible. Los métodos declarados en el cuerpo de la clase aterrizan en Constructor.prototype y por tanto se comparten. Los campos de instancia (incluidas las funciones flecha asignadas como campos) se recrean por instancia: enlace de this garantizado, pero coste de memoria multiplicado. Por último, los campos #private proporcionan privacidad impuesta por el motor, a diferencia de la convención del _guion_bajo.
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 durante una llamada simple fn() sin objeto y sin enlace explícito?this?