Prototipo JavaScript
Sommario: in questo tutorial, imparerete il prototipo JavaScript e come funziona sotto il cappuccio.
Introduzione al prototipo JavaScript
Di default, il JavaScript fornisce la funzione Object():
Code language: JavaScript (javascript)console.log(Object);

Si noti che il Object() è una funzione, non un oggetto. È abbastanza confuso se questa è la prima volta che avete imparato a conoscere il prototipo JavaScript.
Fornisce anche un oggetto anonimo che può essere referenziato tramite la proprietà prototype della funzione Object:
Code language: JavaScript (javascript)console.log(Object.prototype);

La Object.prototype ha molti metodi e proprietà come toString() e valueOf().
Nota quando una funzione è un valore di una proprietà di un oggetto, si chiama metodo. Quindi i metodi sono fondamentalmente proprietà di un oggetto.
Il Object.prototype ha anche un’importante proprietà chiamata constructor che fa riferimento alla funzione Object().
La seguente dichiarazione conferma che la proprietà Object.prototype.constructor fa riferimento alla funzione Object:
Code language: JavaScript (javascript)console.log(Object.prototype.constructor === Object); // true
Supponiamo che un cerchio rappresenta una funzione e un quadrato rappresenta un oggetto.
La figura seguente illustra le relazioni tra la Object() funzione e l’Object.prototype oggetto:

Prima di tutto, definire una funzione costruttrice chiamata Person come segue:
Code language: JavaScript (javascript)function Person(name) { this.name = name;}
In questo esempio, la funzione Person() accetta un argomento name e assegna l’argomento name alla proprietà name dell’oggetto this.
Dietro le quinte, JavaScript crea una nuova funzione Person() e un oggetto anonimo:

Come la funzione Object(), la funzione Person() ha una proprietà chiamata prototype che fa riferimento ad un oggetto anonimo. E l’oggetto anonimo ha la proprietà constructor che fa riferimento alla funzione Person().
Il seguente mostra la funzione Person() e l’oggetto anonimo referenziato dal Person.prototype:
Code language: CSS (css)console.log(Person);console.log(Person.prototype);

Inoltre, JavaScript collega l’oggetto Person.prototype all’oggetto Object.prototype tramite ], che è conosciuto come un collegamento prototipo.
Il collegamento prototipo è indicato da ] nella figura seguente:

Definizione dei metodi nel JavaScript prototipo oggetto
Il seguente definisce un nuovo metodo chiamato greet() nell’oggetto Person.prototype:
Code language: JavaScript (javascript)Person.prototype.greet = function() { return "Hi, I'm " + this.name + "!";}
In questo caso, JavaScript aggiunge il metodo greet() all’oggetto Person.prototype:

Il seguente crea una nuova istanza del Person :
Code language: JavaScript (javascript)let p1 = new Person('John');
Internamente, il motore JavaScript crea un nuovo oggetto chiamato p1 e collega l’oggetto p1 all’oggetto Person.prototype tramite il collegamento prototipo:

Il collegamento di p1Person.prototype, e Object.protoype è chiamato catena prototipale.
Il seguente chiama il metodo greet() sull’oggetto p1:
Code language: JavaScript (javascript)let greeting = p1.greet();console.log(greeting);
Perché p1 non ha il metodo greet(), JavaScript segue il collegamento del prototipo e lo trova sull’oggetto Person.prototype.
Siccome JavaScript può trovare il metodo greet() sull’oggetto Person.prototype, esegue il metodo greet() e ritorna il risultato:

Il seguente chiama il metodo toString() sull’oggetto p1:
Code language: JavaScript (javascript)let s = p1.toString();console.log(s);
In questo caso, JavaScript segue la catena dei prototipi per cercare il metodo toString() nel Person.prototype.
Perché il Person.prototype non ha il metodo toString(), JavaScript segue la catena del prototipo e cerca il metodo toString() nell’oggetto Object.prototype.
Siccome JavaScript può trovare il metodo toString() nel Object.prototype, esegue il metodo toString().

Se si chiama un metodo che non esiste sull’oggetto Person.prototype e Object.prototype, JavaScript seguirà la catena dei prototipi e darà un errore se non riesce a trovare il metodo. Per esempio:
Code language: CSS (css)p1.fly();
Perché il metodo fly() non esiste su nessun oggetto nella catena dei prototipi, JavaScript lancia il seguente errore:
Code language: JavaScript (javascript)TypeError: p1.fly is not a function
Il seguente crea un’altra istanza del Person la cui proprietà name è 'Jane':
Code language: JavaScript (javascript)let p2 = new Person('Jane');

La p2 ha le proprietà e i metodi dell’oggetto p1.
In conclusione, quando si definisce un metodo sull’oggetto prototipo, questo metodo è condiviso da tutte le istanze.
Definizione dei metodi in un oggetto individuale
Di seguito si definisce il metodo say() sull’oggetto p1.
Code language: JavaScript (javascript)p1.draw = function () {return "I can draw.";};
Questa volta JavaScript aggiunge il metodo draw() all’oggetto p1, non all’oggetto Person.prototype:

Significa che potete chiamare il metodo draw() sull’oggetto p1:
Code language: CSS (css)p1.draw();
Ma non potete chiamare il metodo draw() sull’oggetto p2:
Code language: CSS (css)p2.draw()
Errore:
Code language: JavaScript (javascript)TypeError: p2.draw is not a function
Quando si definisce un metodo in un oggetto, il metodo è disponibile solo per quell’oggetto. Non può essere condiviso con altri oggetti per impostazione predefinita.
Aggiungi un collegamento al prototipo
Il __proto__ si pronuncia come dunder proto. Il __proto__ è una proprietà accessoria dell’oggetto Object.prototype. Espone il collegamento interno del prototipo ( ]) di un oggetto attraverso il quale si accede ad esso.
Il __proto__ è stato standardizzato in ES6 per garantire la compatibilità per i browser web. Tuttavia, potrebbe essere deprecato a favore del Object.getPrototypeOf() in futuro. Pertanto, non dovreste mai usare __proto__ nel vostro codice di produzione.
Il p1.__proto__ espone il ] che fa riferimento all’oggetto Person.prototype.
Similmente, anche p2.__proto__ fa riferimento allo stesso oggetto p1.__proto__:
Code language: JavaScript (javascript)console.log(p1.__proto__ === Person.prototype); // trueconsole.log(p1.__proto__ === p2.__proto__); // true
Come detto prima, dovresti usare il metodo Object.getPrototypeOf() invece del metodo __proto__.
Il metodo Object.getPrototypeOf() restituisce il prototipo di un oggetto specificato.
Code language: JavaScript (javascript)console.log(p1.__proto__ === Object.getPrototypeOf(p1)); // true
Un altro modo popolare per ottenere il collegamento del prototipo quando il metodo Object.getPrototypeOf() non era disponibile è tramite la proprietà constructor come segue:
Code language: CSS (css)p1.constructor.prototype
Il p1.constructor restituisce Person, quindi, p1.constructor.prototype ritorna l’oggetto prototipo.
Shadowing
Vedi la seguente chiamata di metodo:
Code language: CSS (css)console.log(p1.greet());
L’oggetto p1 non ha il metodo greet() definito, quindi JavaScript risale la catena del prototipo per trovarlo. In questo caso, può trovare il metodo nell’oggetto Person.prototype.
Aggiungiamo un nuovo metodo all’oggetto p1 con lo stesso nome del metodo nell’oggetto Person.prototype:
Code language: JavaScript (javascript)p1.greet = function() { console.log('Hello');}
E chiamiamo il metodo greet():
Code language: CSS (css)console.log(p1.greet());
Perché l’oggetto p1 ha il metodo greet(), JavaScript lo esegue immediatamente senza cercarlo nella catena del prototipo.
Questo è un esempio di shadowing. Il metodo greet() dell’oggetto p1 fa ombra al metodo greet() dell’oggetto prototype che l’oggetto p1 referenzia.
Sommario
- La funzione
Object()ha una proprietà chiamataprototypeche fa riferimento a un oggettoObject.prototype. - L’oggetto
Object.prototypeha tutte le proprietà e i metodi che sono disponibili in tutti gli oggetti cometoString()evalueOf(). - L’oggetto
Object.prototypeha la proprietàconstructorche fa riferimento alla funzioneObject. - Ogni funzione ha un oggetto
prototype. Questo oggetto prototipo fa riferimento all’oggettoObject.prototypetramite il collegamento]o la proprietà__proto__. - La catena prototipo permette ad un oggetto di utilizzare i metodi e le proprietà dei suoi oggetti
prototypetramite i collegamenti]. - Il metodo
Object.getPrototypeOf()restituisce l’oggetto prototipo di un dato oggetto. Usate il metodoObject.getPrototypeOf()invece di__proto__.
- Questo tutorial è stato utile ?
- SìNo