"Sono stato bocciato a parecchi esami. Un mio amico invece, li ha passati tutti a pieni voti. Ora è ingegnere e lavora in Microsoft. Io sono il proprietario."  - Bill Gates  •  "Se riesco a fare qualcosa in 10 minuti, è perché ho passato anni a studiarlo."  - Bill Gates  •  "Il vostro lavoro riempirà gran parte della vostra vita, e l'unico modo per essere veramente soddisfatti è fare ciò che ritenete sia un grande lavoro."  - Steve Jobs  •  "Siate affamati. Siate folli."  - Steve Jobs  •  

cinque 

ZERO

{JS} Prototype & Object.create()

home / javascript /

Lucio Asciolla

Full Stack Developer

Indice

JavaScript ci permette di modificare la struttura degli oggetti anche dopo la creazione grazie alla sua flessibilità.

Abbiamo già visto come creare un "costruttore" di oggetti; riproponiamo il costruttore di utenti:

function Utente(nome, cognome, email) {
    this.nome = nome,
    this.cognome = cognome,
    this.email = email
}

Creato il nostro costruttore possiamo riutilizzarlo per la creazione di diversi utenti:

var marioRossi = new Utente("Mario", "Rossi", "mario.rossi@gmail.com");
var lucaBianchi = new Utente("Luca", "Bianchi", "luca.bianchi@gmail.com");

Sappiamo anche come aggiungere una proprietà o un metodo ad un oggetto:

marioRossi.telefono = "+393303132333";
marioRossi.saluto = function(){
return "Ciao sono " + this.nome + this.cognome + " !";
}

prototype

Con la proprietà "prototype" dell'oggetto globale Object, possiamo leggere ,indicare il prototipo di riferimento ed aggiungere proprietà agli stessi prototipi.

Gerarchica dei prototipi

Tutti gli oggetti in Javascript hanno un prototipo o più prototipi, come detto, la ricerca di proprietà e metodi risale sino ad identificare quale prototipo la possiede secondo una catena gerarchica ben precisa.

1Object
2Oggetti predefiniti
3Costruttori personalizzati

La ricerca di una proprietà o di un metodo risale la catena dei prototipi fino ad arrivare all’oggetto Object, il prototipo base di tutti gli oggetti.

Leggere il prototipo di riferimento

var prototipo = marioRossi.prototype;
console.log(prototipo); // Restituirà "Utente"

Aggiungere proprietà alle istanze dei prototipi

Con prototype possiamo anche aggiungere proprietà a tutte le istanze dei prototipi.

Prototipi sono tutti gli oggetti predefiniti, l'oggetto capostipite Object, e tutti i nostri costruttori di oggetti.

utente.prototype.codiceFiscale;
utente.prototype.saluto = function(){
return "Ciao sono " + this.nome + this.cognome + " !";
}

Cosi facendo la proprietà "codiceFiscale" ed il metodo "saluto" saranno aggiunta a tutte le istanze dell'oggetto "Persona".

Nota: Le proprietà viengono aggiunte a tutte le istanze di oggetti generati ma non al costruttore.

Aggiungere proprietà e metodi agli oggetti predefiniti

Attraverso prototype è possibile aggiungere proprietà e metodi agli oggetti predefiniti in modo da renderli accessibili a tutte le loro istanze.

String.prototype.firma= function(){
return " <br>" + "Pubblicato da cinquepuntozero.it";
}

var articolo = new String("Lorem ipsum dolor sit amet, consectetur adipisci elit");
document.write(articolo + articolo.firma());

E' stata implementata nell'oggetto String ed è ereditata dalla istanza "articolo" creata attraverso lo stesso oggetto.
Quindi all'invocazione del metodo firma() la ricerca è risalita sino all'oggetto predefinito/costruttore.

Impostare/cambiare il prototipo di riferimento

Per effettuare il cambio impostazione del prototipo creiamo un nuovo costrutto "Admin"

function Admin(nome, cognome, email, reparto) {
    this.nome = nome,
    this.cognome = cognome,
    this.email = email,
    this.reparto = reparto
}

Con il metodo .create() dell'oggetto Object possiamo indicare il nuovo prototipo di riferimento

marioRossi.prototype = Object.create(Admin.prototype);

Prototipi sono tutti gli oggetti predefiniti, l'oggetto capostipite Object, e tutti i nostri costruttori di oggetti.

Object.create()

Con il metodo .create() dell'oggetto Object possiamo creare un oggetto indicando preventivamente il prototipo di riferimento.

var articolo = new Object.create(String.prototype);

Questo tipo di sintassi, rispetto alla classica sintassi

var articolo = new String("");

apre a nuove e maggiori possibilità di configurazione delle proprietà degli oggetti.

Esempi di sintassi

Oggetto vuoto senza prototipo di riferimento

var articolo = Object.create(null);

Oggetto vuoto con prototipo di riferimento

var articolo = new Object.create(String.prototype);

Oggetto con prototipo di riferimento e proprietà

var marioRossi = Object.create(Persona.prototype, {
nome:{                                     
value: "Mario" },
cognome:{
value: "Rossi" }
});

I descrittori delle proprietà

Un descrittore, come il precedente visto "value", è un oggetto che definisce caratteristiche e modalità di accesso alle proprietà di un oggetto.

Di descrittori di proprietà nè esistono due tipi:

Data descriptorspecifica una serie di caratteristiche per le proprietà di un oggetto
Accessor descriptordefinisce due modalità di accesso per i metodi di un oggetto

Data descriptor

Serie di caratteristiche per le proprietà di un oggetto

writableBooleano che indica se il valore della proprietà può essere modificato
configurableBooleano che indica se il tipo di descrittore può essere modificato e se la proprietà può essere rimossa
enumerableBooleano che indica se la proprietà è accessibile durante un ciclo sulle proprietà dell’oggetto
valueIndica il valore della proprietà
var marioRossi = Object.create(persona.prototype, {

nome: {
value        : "Mario",
writable     : false,
configurable : false },

cognome: {
value        : "Rossi",
writable     : false,
configurable : false },
  
indirizzo: {
value        : "",
writable     : true,
configurable : true }

});
Accessor descriptor

Definisce due modalità di accesso per i metodi di un oggetto

getcomportamento se si invocata un metodo di un oggetto senza passare valori (proprietà in lettura)
setcomportamento se si invocata un metodo di un oggetto con passaggio di valori (proprietà in scrittura)
var marioRossi = Object.create(Persona.prototype, {

nome: {
value        : "Mario",
writable     : false,
configurable : false },

saluta: {
get: function() {
     return "Ciao " + this.nome + "!" ; },
set: function(value) {
     return "Ciao " + this.nome +" da " + value +"!"; },
}                                                                          }
                                                                                       });

L'invocazione di del metodo "saluta()" dell'oggetto "marioRossi" mostrerà differenti risultati a seconda se invocato con o senza paramento.

marioRossi.saluta()
// Ciao Mario!
marioRossi.saluta("Giovanni");
// Ciao Mario da Giovanni!
Argomenti collegati