Articles

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():

console.log(Object);
Code language: JavaScript (javascript)

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:

console.log(Object.prototype);
Code language: JavaScript (javascript)

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:

console.log(Object.prototype.constructor === Object); // true
Code language: JavaScript (javascript)

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:

function Person(name) { this.name = name;}
Code language: JavaScript (javascript)

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:

console.log(Person);console.log(Person.prototype);
Code language: CSS (css)

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:

Person.prototype.greet = function() { return "Hi, I'm " + this.name + "!";}
Code language: JavaScript (javascript)

In questo caso, JavaScript aggiunge il metodo greet() all’oggetto Person.prototype:

Il seguente crea una nuova istanza del Person :

let p1 = new Person('John');
Code language: JavaScript (javascript)

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:

let greeting = p1.greet();console.log(greeting);
Code language: JavaScript (javascript)

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:

let s = p1.toString();console.log(s);
Code language: JavaScript (javascript)

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:

p1.fly();
Code language: CSS (css)

Perché il metodo fly() non esiste su nessun oggetto nella catena dei prototipi, JavaScript lancia il seguente errore:

TypeError: p1.fly is not a function
Code language: JavaScript (javascript)

Il seguente crea un’altra istanza del Person la cui proprietà name è 'Jane':

let p2 = new Person('Jane');
Code language: JavaScript (javascript)

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.

p1.draw = function () {return "I can draw.";};
Code language: JavaScript (javascript)

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:

p1.draw();
Code language: CSS (css)

Ma non potete chiamare il metodo draw() sull’oggetto p2:

p2.draw()
Code language: CSS (css)

Errore:

TypeError: p2.draw is not a function
Code language: JavaScript (javascript)

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__:

console.log(p1.__proto__ === Person.prototype); // trueconsole.log(p1.__proto__ === p2.__proto__); // true
Code language: JavaScript (javascript)

Come detto prima, dovresti usare il metodo Object.getPrototypeOf() invece del metodo __proto__.

Il metodo Object.getPrototypeOf() restituisce il prototipo di un oggetto specificato.

console.log(p1.__proto__ === Object.getPrototypeOf(p1)); // true
Code language: JavaScript (javascript)

Un altro modo popolare per ottenere il collegamento del prototipo quando il metodo Object.getPrototypeOf() non era disponibile è tramite la proprietà constructor come segue:

p1.constructor.prototype
Code language: CSS (css)

Il p1.constructor restituisce Person, quindi, p1.constructor.prototype ritorna l’oggetto prototipo.

Shadowing

Vedi la seguente chiamata di metodo:

console.log(p1.greet());
Code language: CSS (css)

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:

p1.greet = function() { console.log('Hello');}
Code language: JavaScript (javascript)

E chiamiamo il metodo greet():

console.log(p1.greet());
Code language: CSS (css)

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à chiamata prototype che fa riferimento a un oggetto Object.prototype.
  • L’oggetto Object.prototype ha tutte le proprietà e i metodi che sono disponibili in tutti gli oggetti come toString() e valueOf().
  • L’oggetto Object.prototype ha la proprietà constructor che fa riferimento alla funzione Object.
  • Ogni funzione ha un oggetto prototype. Questo oggetto prototipo fa riferimento all’oggetto Object.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 metodo Object.getPrototypeOf() invece di __proto__.
  • Questo tutorial è stato utile ?
  • SìNo

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *