Conosco molti modi per creare oggetti JS ma non conoscevo Object.create(null)quello.
Domanda:
è esattamente lo stesso di:
var p = {}
vs
var p2 = Object.create(null);
?
Conosco molti modi per creare oggetti JS ma non conoscevo Object.create(null)quello.
Domanda:
è esattamente lo stesso di:
var p = {}
vs
var p2 = Object.create(null);
?
Risposte:
Non sono equivalenti. {}.constructor.prototype == Object.prototypementre Object.create(null)non eredita da nulla e quindi non ha alcuna proprietà.
In altre parole: un oggetto JavaScript eredita da oggetto per impostazione predefinita, a meno che non si crea esplicitamente con null come il suo prototipo, come: Object.create(null).
{}sarebbe invece equivalente a Object.create(Object.prototype).
In Chrome Devtool puoi vedere che Object.create(null)non ha __proto__proprietà, mentre lo {}fa.
Non sono assolutamente equivalenti. Sto scrivendo questa risposta per spiegare meglio perché fa la differenza.
var p = {};
Crea un oggetto che eredita le proprietà e i metodi da Object.
var p2 = Object.create(null);
Crea un oggetto che non eredita nulla.
Se stai usando un oggetto come mappa e crei un oggetto usando il metodo 1 sopra, devi fare molta attenzione quando esegui ricerche nella mappa. Poiché le proprietà e i metodi di Objectsono ereditati, il codice potrebbe incorrere in un caso in cui nella mappa sono presenti chiavi che non sono mai state inserite. Ad esempio, se si eseguisse una ricerca toString, si troverà una funzione, anche se non si inserisce mai quel valore lì. Puoi aggirare questo in questo modo:
if (Object.prototype.hasOwnProperty.call(p, 'toString')) {
// we actually inserted a 'toString' key into p
}
Si noti che è bene assegnare qualcosa a p.toString, semplicemente sostituirà la toStringfunzione ereditata su p.
Nota che non puoi semplicemente farlo p.hasOwnProperty('toString')perché potresti aver inserito una chiave "hasOwnProperty" in p, quindi lo forziamo a usare l'implementazione in Object.
D'altra parte, se usi il metodo 2 sopra, non dovrai preoccuparti che le cose Objectappaiano nella mappa.
Non puoi verificare l'esistenza di una proprietà con un semplice ifcome questo:
// Unreliable:
if (p[someKey]) {
// ...
}
Il valore potrebbe essere una stringa vuota, potrebbe essere false, oppure nulloppure oppure oppure undefinedoppure 0oppure NaN, ecc. Per verificare l'esistenza di una proprietà, è comunque necessario utilizzarla Object.prototype.hasOwnProperty.call(p, someKey).
Object.create(null). Preferisco non fare ipotesi del genere, anche se avessi assolutamente ragione Object.create(null), il codice potrebbe cambiare, l'oggetto potrebbe essere sostituito con uno che eredita Objectad un certo punto. hasOwnPropertyfunziona sempre.
{}è molto più diffuso che Object.create(null), se il tuo codice prende accidentalmente una proprietà ereditata a questo punto, probabilmente avrai bug molto più grandi di cui preoccuparti. Vedo solo le persone che usano Object.create (null) come un'ottimizzazione minore.
!!p[key]funziona bene Object.create(null). Ma hasKey = (key, input) => Object.prototype.hasOwnProperty.call(input, key)non è neanche male
pperché ogni metodo potrebbe essere inserito e quindi non essere sicuro.
La creazione di oggetti mediante l'utilizzo {}creerà un oggetto il cui prototipo è Object.prototypeche eredita le funzioni di base dal Objectprototipo, mentre la creazione di oggetti mediante l'utilizzo Object.create(null)creerà un oggetto vuoto il cui prototipo è nullo.
Se qualcuno sta cercando l'implementazione Object.create(null), solo per sapere come funziona. È scritto usando un __proto__metodo non standard e quindi non lo consiglio .
function objectCreateMimic()
{
/*optional parameters: prototype_object, own_properties*/
var P = arguments.length>0?arguments[0]:-1;
var Q = arguments.length>1?arguments[1]:null;
var o = {};
if(P!==null && typeof P === "object")
{
o.__proto__ = P;
}
else if(P===null)
{
o.__proto__ = null;
}
if(Q!==null && typeof Q === "object")
{
for(var key in Q)
{
o[key] = Q[key];
}
}
return o;
}
Nota : l'ho scritto per curiosità ed è scritto solo in termini semplici, ad esempio, non trasferisco i descrittori di proprietà dal secondo oggetto all'oggetto return.
__proto__diventerà ufficialmente parte della lingua.
-1dentro arguments.length>0?arguments[0]:-1;?
Objectprototipo venga mantenuto se non viene fornito il primo argomento. I nomi delle variabili potrebbero essere molto meglio qui.
Quando si crea un oggetto con Object.create (null) significa che si sta creando un oggetto senza prototipo. null qui significa fine della catena del prototipo. Tuttavia, quando si crea un oggetto come {} verrà aggiunto il prototipo di oggetto. Quindi questi sono due oggetti diversi, uno con prototipo un altro senza prototipo. Spero che questo aiuti
if (someKey in p) {