Ich kenne viele Möglichkeiten, um JS-Objekte zu erstellen, aber ich kannte das nicht Object.create(null).
Frage:
ist es genau das gleiche wie:
var p = {}
vs.
var p2 = Object.create(null);
?
Ich kenne viele Möglichkeiten, um JS-Objekte zu erstellen, aber ich kannte das nicht Object.create(null).
Frage:
ist es genau das gleiche wie:
var p = {}
vs.
var p2 = Object.create(null);
?
Antworten:
Sie sind nicht gleichwertig. {}.constructor.prototype == Object.prototypewährend Object.create(null)erbt von nichts und hat daher überhaupt keine Eigenschaften.
Mit anderen Worten: Ein Javascript-Objekt erbt standardmäßig von Object, es sei denn, Sie erstellen es explizit mit null als Prototyp, z Object.create(null).
{}wäre stattdessen gleichbedeutend mit Object.create(Object.prototype).
In Chrome Devtool können Sie sehen, dass dies Object.create(null)keine __proto__Eigenschaft hat, während dies der {}Fall ist.
Sie sind definitiv nicht gleichwertig. Ich schreibe diese Antwort, um genauer zu erklären, warum es einen Unterschied macht.
var p = {};
Erstellt ein Objekt, von dem die Eigenschaften und Methoden geerbt werden Object.
var p2 = Object.create(null);
Erstellt ein Objekt, das nichts erbt.
Wenn Sie ein Objekt als Karte verwenden und ein Objekt mit der obigen Methode 1 erstellen, müssen Sie beim Nachschlagen in der Karte besonders vorsichtig sein. Da die Eigenschaften und Methoden von Objectgeerbt werden, kann Ihr Code in einen Fall geraten, in dem die Karte Schlüssel enthält, die Sie nie eingefügt haben. Wenn Sie beispielsweise nachschlagen toString, finden Sie eine Funktion, obwohl Sie diesen Wert dort nie angegeben haben. Sie können das folgendermaßen umgehen:
if (Object.prototype.hasOwnProperty.call(p, 'toString')) {
// we actually inserted a 'toString' key into p
}
Beachten Sie, dass es in Ordnung ist, etwas zuzuweisen p.toString, da es einfach die geerbte toStringFunktion überschreibt p.
Beachten Sie, dass Sie dies nicht einfach tun können, p.hasOwnProperty('toString')weil Sie möglicherweise einen Schlüssel "hasOwnProperty" eingefügt haben. Daher perzwingen wir, dass die Implementierung in verwendet wird Object.
Wenn Sie dagegen Methode 2 oben verwenden, müssen Sie sich keine Sorgen machen, dass Dinge Objectin der Karte angezeigt werden.
Mit einem einfachen ifBeispiel können Sie nicht prüfen, ob eine Eigenschaft vorhanden ist :
// Unreliable:
if (p[someKey]) {
// ...
}
Der Wert kann eine leere Zeichenfolge sein false, oder nulloder oder oder undefinedoder 0oder NaNusw. Um zu überprüfen, ob überhaupt eine Eigenschaft vorhanden ist, müssen Sie diese noch verwenden Object.prototype.hasOwnProperty.call(p, someKey).
Object.create(null). Ich ziehe es vor Object.create(null), solche Annahmen nicht zu treffen, selbst wenn Sie absolut Recht hätten, dass sie verwendet werden , könnte sich der Code ändern, das Objekt könnte durch eines ersetzt werden, das Objectirgendwann erbt . hasOwnPropertyfunktioniert immer.
{}es so viel häufiger vorkommt Object.create(null), dass Sie wahrscheinlich größere Fehler befürchten müssen, wenn Ihr Code an dieser Stelle versehentlich eine geerbte Eigenschaft erfasst. Ich kann nur Leute sehen, die Object.create (null) als geringfügige Optimierung verwenden.
!!p[key]funktioniert gut mit Object.create(null). hasKey = (key, input) => Object.prototype.hasOwnProperty.call(input, key)
pda jede Methode eingefügt werden kann und daher nicht sicher ist.
Durch das Erstellen von Objekten mithilfe von {}wird ein Objekt erstellt, dessen Prototyp Object.prototypedie Grundfunktionen des ObjectPrototyps erbt. Beim Erstellen von Objekten mithilfe von Object.create(null)wird ein leeres Objekt erstellt, dessen Prototyp null ist.
Wenn jemand nach einer Implementierung sucht Object.create(null), nur um zu wissen, wie es funktioniert. Es ist so geschrieben, __proto__dass es nicht dem Standard entspricht, und daher empfehle ich es nicht .
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;
}
Hinweis : Ich habe dies aus Neugier geschrieben und es ist nur in einfachen Worten geschrieben. Beispielsweise übertrage ich die Eigenschaftsbeschreibungen nicht vom zweiten Objekt auf das Rückgabeobjekt.
-1in arguments.length>0?arguments[0]:-1;?
ObjectPrototyp beibehalten wird, wenn das erste Argument nicht angegeben wird. Variablennamen könnten hier viel besser sein.
Wenn Sie ein Objekt mit Object.create (null) erstellen, bedeutet dies, dass Sie ein Objekt ohne Prototyp erstellen. null bedeutet hier das Ende der Prototypkette. Wenn Sie jedoch ein Objekt wie {} erstellen, wird ein Objektprototyp hinzugefügt. Daher sind dies zwei verschiedene Objekte, eines mit Prototyp und eines ohne Prototyp. Hoffentlich hilft dies
if (someKey in p) {