Crea un oggetto con lo stesso costruttore
Immagina di avere un oggetto arbitrario obj
, creato da un costruttore – non sappiamo quale, ma vorremmo poter creare un nuovo oggetto utilizzandolo.
Possiamo farlo in questo modo?
let obj2 = new obj.constructor();
Fornite un esempio di costruttore per obj
che permetta a questo codice di funzionare correttamente. Ed un esempio che non lo farebbe funzionare.
Possiamo utilizzare questo approccio se siamo sicuri che il "constructor"
possiede il valore corretto.
Ad esempio, se non tocchiamo il "prototype"
di default, allora il codice funzionerà di sicuro:
function User(name) {
this.name = name;
}
let user = new User('John');
let user2 = new user.constructor('Pete');
alert( user2.name ); // Pete (ha funzionato!)
Ha funzionato, poiché User.prototype.constructor == User
.
…Ma se qualcuno, per un qualsiasi motivo, sovrascrivesse User.prototype
e dimenticasse di ricreare il constructor
di riferimento a User
, allora fallirebbe.
Ad esempio:
function User(name) {
this.name = name;
}
User.prototype = {}; // (*)
let user = new User('John');
let user2 = new user.constructor('Pete');
alert( user2.name ); // undefined
Perché user2.name
è undefined
?
Ecco come new user.constructor('Pete')
funziona:
- Prima, controlla se esiste
constructor
inuser
. Niente. - Successivamente segue la catena di prototype. Il prototype di
user
èUser.prototype
, e anche qui non c’è unconstructor
(perché ci siamo “dimenticati” di impostarlo!). - Seguendo la catena,
User.prototype
è un oggetto semplice, il suo prototype èObject.prototype
. - Infine, per
Object.prototype
, c’èObject.prototype.constructor == Object
. Quindi verrà utilizzato.
In conclusione, abbiamo let user2 = new Object('Pete')
.
Probabilmente, non è quello che avremmo voluto, ossia creare new User
, non new Object
. Questo è il risultato del costruttore
mancante.
(Nel caso tu sia curioso, la chiamata new Object(...)
converte il suo argomento in un oggetto. Questa è una cosa teorica, in pratica nessuno chiama new Object
con un valore, e generalmente non usiamo mai new Object
per creare oggetti.