Spiega come funziona l'ereditarietà in JavaScript.
sobes.tech AI
Risposta dell'AI
L'ereditarietà in JavaScript viene implementata tramite prototipi. Ogni oggetto in JavaScript ha una proprietà interna [[Prototype]] che fa riferimento a un altro oggetto. Quando si tenta di accedere a una proprietà o metodo di un oggetto che non è presente direttamente su di esso, il motore JavaScript cerca questa proprietà o metodo nel prototipo di quell'oggetto. Se non lo trova, continua la ricerca lungo la catena di prototipi, che si forma tramite le connessioni [[Prototype]], fino a raggiungere null (fine della catena).
Esistono due meccanismi principali di ereditarietà:
-
Ereditarietà prototipica classica (ES5 e precedenti): Basata sull'uso di funzioni costruttore e sulla loro proprietà
prototype.// Funzione costruttore function Animal(name) { this.name = name; } // Aggiunta di metodo al prototipo Animal.prototype.speak = function() { console.log(`${this.name} emette un suono.`); }; // Creazione di un'istanza const dog = new Animal('Cane'); // Chiamata del metodo dal prototipo dog.speak(); // Stampa: Cane emette un suono. // Il prototipo di cat è Animal.prototype console.log(Object.getPrototypeOf(dog) === Animal.prototype); // true -
Ereditarietà basata su classi (ES6 e successivi): Usa la sintassi
classeextends, che internamente opera comunque con i prototipi.// Classe base class Animal { constructor(name) { this.name = name; } speak() { console.log(`${this.name} emette un suono.`); } } // Sottoclasse che eredita da Animal class Dog extends Animal { constructor(name, breeds) { super(name); // Chiamata al costruttore della classe genitore this.breeds = breeds; } bark() { console.log(`${this.name} abbaia.`); } } // Creazione di un'istanza della sottoclasse const myDog = new Dog('Bublik', ['Labrador', 'Collie']); // Chiamata ai metodi di Animal e Dog myDog.speak(); // Stampa: Bublik emette un suono. myDog.bark(); // Stampa: Bublik abbaia. // Il prototipo di myDog è Dog.prototype console.log(Object.getPrototypeOf(myDog) === Dog.prototype); // true // Il prototipo di Dog.prototype è Animal.prototype console.log(Object.getPrototypeOf(Dog.prototype) === Animal.prototype); // true
Concetti chiave:
-
Catenza di prototipi: La relazione tra oggetti tramite i loro
[[Prototype]]. -
__proto__(obsoleto/non standard, ma utile per capire): Proprietà tramite cui si può accedere a[[Prototype]]. Non si consiglia di usarlo in produzione. -
Object.getPrototypeOf(obj): Metodo standard per ottenere il prototipo di un oggetto. -
Object.setPrototypeOf(obj, proto): Metodo standard per modificare il prototipo di un oggetto (non si consiglia di modificarlo dopo la creazione di un oggetto esistente). -
instanceof: Operatore per verificare se un oggetto è istanza di una classe o funzione costruttrice, controllando la sua catena di prototipi.console.log(myDog instanceof Dog); // true console.log(myDog instanceof Animal); // true console.log(myDog instanceof Object); // true (alla fine della catena Object.prototype) -
super: Usato nelle classi per chiamare metodi o il costruttore della classe genitore.
La differenza tra approccio classico e basato su classi: Le classi offrono un modo più strutturato e sintatticamente comodo di lavorare con l'ereditarietà prototipica, simile ad altri linguaggi di programmazione. Tuttavia, il meccanismo di base rimane lo stesso — ereditarietà tramite prototipi.