Nel primo capitolo di questa sezione, abbiamo menzionato il fatto che esistono metodi piu moderni per impostare il prototype.
La proprietà __proto__ viene considerata datata, e in un certo senso anche deprecata (negli standard JavaScript per i browser).
Alcuni dei metodi più moderni sono:
- Object.create(proto, [descriptors]) – crea un oggetto vuoto, impostando il
protocome[[Prototype]]e dei descrittori di proprietà opzionali. - Object.getPrototypeOf(obj) – ritorna il
[[Prototype]]diobj. - Object.setPrototypeOf(obj, proto) – imposta il
[[Prototype]]diobjaproto.
Questi metodi dovrebbero sempre essere preferiti a __proto__.
Ad esempio:
let animal = {
eats: true
};
// creiamo un nuovo oggetto con animal come prototype
let rabbit = Object.create(animal);
alert(rabbit.eats); // true
alert(Object.getPrototypeOf(rabbit) === animal); // true
Object.setPrototypeOf(rabbit, {}); // cambia il prototype di rabbit a {}
Object.create supporta un secondo argomento opzionale: il property descriptors (descrittori di proprietà). Possiamo fornire proprietà aggiuntive al nuovo oggetto, in questo modo:
let animal = {
eats: true
};
let rabbit = Object.create(animal, {
jumps: {
value: true
}
});
alert(rabbit.jumps); // true
I descrittori vanno forniti nel formato descritto nel capitolo Attributi e descrittori di proprietà.
Possiamo utilizzare Object.create per clonare un oggetto in maniera più efficace rispetto al copiare le proprietà con un for..in:
let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
Questa chiamata crea una copia esatta di obj, inculdendo tutte le proprietà: enumerable e non-enumerable, e i relativi setters/getters – tutto, impostando anche il giusto [[Prototype]].
Una breve storia
Se contiamo tutti i modi che abbiamo a disposizione per gestire [[Prototype]], questi sono molti! Abbiamo moltissime modalità per fare la stessa cosa!
Perché?
Motivazioni storiche.
- La proprietà
"prototype"di un costruttore è disponibile fin dai primi tempi in JavaScript. - Più tardi, nel 2012, è apparso nello standard
Object.create. Il quale permette di creare oggetti fornendogli un prototype, ma non consente di impostarlo o di ottenerlo. Quindi i browser implementarono il metodo non-standard__proto__, come proprietà di accesso per impostare o otternere il prototype in qualsiasi momento.