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 p1
Person.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à chiamataprototype
che fa riferimento a un oggettoObject.prototype
. - L’oggetto
Object.prototype
ha tutte le proprietà e i metodi che sono disponibili in tutti gli oggetti cometoString()
evalueOf()
. - L’oggetto
Object.prototype
ha la proprietàconstructor
che fa riferimento alla funzioneObject
. - Ogni funzione ha un oggetto
prototype
. Questo oggetto prototipo fa riferimento all’oggettoObject.prototype
tramite il collegamento]
o la proprietà__proto__
. - La catena prototipo permette ad un oggetto di utilizzare i metodi e le proprietà dei suoi oggetti
prototype
tramite 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