Cos'è l'ereditarietà prototipica in JavaScript?
sobes.tech AI
Risposta dell'AI
In JavaScript, gli oggetti ereditano proprietà e metodi dai loro prototipi. Il prototipo di ogni oggetto è un altro oggetto, le cui proprietà e metodi sono accessibili attraverso la catena dei prototipi.
Quando si accede a una proprietà di un oggetto, JavaScript la cerca prima direttamente nell'oggetto stesso. Se la proprietà non viene trovata, la ricerca continua nel prototipo di quell'oggetto, poi nel prototipo del prototipo, e così via, fino a trovare la proprietà o raggiungere la fine della catena (null).
L'ereditarietà prototipica si differenzia dall'ereditarietà classica (come in Java o C++), dove gli oggetti vengono creati da classi che descrivono la loro struttura e comportamento. In JavaScript, le classi, introdotte in ES6, sono uno zucchero sintattico sopra l'ereditarietà prototipica.
Aspetti principali:
- __proto__: Proprietà interna dell'oggetto che fa riferimento al suo prototipo.
- prototype: Proprietà del costruttore (funzione usata come costruttore), che fa riferimento all'oggetto che fungerà da prototipo per le istanze create.
- Object.getPrototypeOf(obj): Metodo standard per ottenere il prototipo di un oggetto.
- Object.setPrototypeOf(obj, proto): Metodo standard per impostare il prototipo di un oggetto.
Esempio:
// Funzione costruttrice
function Animal(name) {
this.name = name;
}
// Aggiungi metodo al prototipo Animal
Animal.prototype.sayHello = function() {
console.log(`Ciao, il mio nome è ${this.name}`);
};
// Crea un'istanza
const dog = new Animal("Buddy");
// Chiama metodo dal prototipo
dog.sayHello(); // Output: Ciao, il mio nome è Buddy
// Il prototipo di dog è Animal.prototype
console.log(Object.getPrototypeOf(dog) === Animal.prototype); // true
// Il prototipo di Animal.prototype è Object.prototype
console.log(Object.getPrototypeOf(Animal.prototype) === Object.prototype); // true
// La fine della catena dei prototipi è null
console.log(Object.getPrototypeOf(Object.prototype) === null); // true
Confronto con l'ereditarietà classica (usando classi ES6):
class Animal {
constructor(name) {
this.name = name;
}
sayHello() {
console.log(`Ciao, il mio nome è ${this.name}`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // Chiamata al costruttore della classe genitore
this.breed = breed;
}
bark() {
console.log("Woof!");
}
}
const buddy = new Dog("Buddy", "Golden Retriever");
buddy.sayHello(); // Output: Ciao, il mio nome è Buddy (eredita da Animal)
buddy.bark(); // Output: Woof! (metodo di Dog)
// Le classi in ES6 sono zucchero sintattico sopra i prototipi
console.log(Object.getPrototypeOf(Dog) === Animal); // true (ereditarietà di classi)
console.log(Object.getPrototypeOf(Dog.prototype) === Animal.prototype); // true (ereditarietà di metodi tramite prototipi)
console.log(Object.getPrototypeOf(buddy) === Dog.prototype); // true (l'istanza eredita dal prototipo della classe)
L'ereditarietà prototipica è un concetto chiave in JavaScript, la cui comprensione è essenziale per lavorare efficacemente con il linguaggio.