Je connais beaucoup de façons de créer des objets JS mais je ne connaissais pas Object.create(null)
celui de.
Question:
est-ce exactement la même chose que:
var p = {}
contre
var p2 = Object.create(null);
?
Je connais beaucoup de façons de créer des objets JS mais je ne connaissais pas Object.create(null)
celui de.
Question:
est-ce exactement la même chose que:
var p = {}
contre
var p2 = Object.create(null);
?
Réponses:
Ils ne sont pas équivalents. {}.constructor.prototype == Object.prototype
while Object.create(null)
n'hérite de rien et n'a donc aucune propriété.
En d' autres termes: un objet javascript hérite de l' objet par défaut, sauf si vous créez explicitement avec NULL comme son prototype, comme: Object.create(null)
.
{}
serait plutôt équivalent à Object.create(Object.prototype)
.
Dans Chrome Devtool, vous pouvez voir que cela Object.create(null)
n'a pas de __proto__
propriété, alors que c'est le {}
cas.
Ils ne sont certainement pas équivalents. J'écris cette réponse pour expliquer plus en détail pourquoi cela fait une différence.
var p = {};
Crée un objet qui hérite des propriétés et des méthodes de Object
.
var p2 = Object.create(null);
Crée un objet qui n'hérite de rien.
Si vous utilisez un objet comme carte et que vous créez un objet à l'aide de la méthode 1 ci-dessus, vous devez faire très attention lorsque vous effectuez des recherches sur la carte. Étant donné que les propriétés et les méthodes de Object
sont héritées, votre code peut s'exécuter dans un cas où il y a des clés dans la carte que vous n'avez jamais insérées. Par exemple, si vous effectuez une recherche sur toString
, vous trouverez une fonction, même si vous n'y mettez jamais cette valeur. Vous pouvez contourner cela comme ceci:
if (Object.prototype.hasOwnProperty.call(p, 'toString')) {
// we actually inserted a 'toString' key into p
}
Notez que vous pouvez attribuer quelque chose à p.toString
, cela remplacera simplement la toString
fonction héritée sur p
.
Notez que vous ne pouvez pas le faire simplement p.hasOwnProperty('toString')
parce que vous avez peut-être inséré une clé "hasOwnProperty" dans p
, nous le forçons donc à utiliser l'implémentation dans Object
.
D'un autre côté, si vous utilisez la méthode 2 ci-dessus, vous n'aurez pas à vous soucier de l' Object
apparition d'éléments sur la carte.
Vous ne pouvez pas vérifier l'existence d'une propriété avec un simple if
comme celui-ci:
// Unreliable:
if (p[someKey]) {
// ...
}
La valeur peut être une chaîne vide, peut être false
, ou null
, ou undefined
, ou 0
, ou NaN
, etc. Pour vérifier si une propriété existe, vous devez toujours l'utiliser Object.prototype.hasOwnProperty.call(p, someKey)
.
Object.create(null)
. Je préfère ne pas faire d'hypothèses comme ça, même si vous aviez tout à fait raison de dire qu'il utilisait Object.create(null)
, le code pourrait changer, l'objet pourrait être remplacé par un qui hérite Object
à un moment donné. hasOwnProperty
fonctionne toujours.
{}
est tellement plus répandu Object.create(null)
que si votre code saisit accidentellement une propriété héritée à ce stade, vous avez probablement des bogues beaucoup plus importants à craindre. Je ne vois que des personnes utilisant Object.create (null) comme une optimisation mineure.
!!p[key]
fonctionne bien avec Object.create(null)
. Mais ce hasKey = (key, input) => Object.prototype.hasOwnProperty.call(input, key)
n'est pas mal non plus
p
car chaque méthode pourrait être insérée et ainsi devenir dangereuse.
La création d'objets à l'aide de {}
créera un objet dont le prototype Object.prototype
hérite des fonctions de base du Object
prototype tandis que la création d'objets à l'aide de Object.create(null)
créera un objet vide dont le prototype est nul.
Si quelqu'un cherche à mettre en œuvre Object.create(null)
, juste pour savoir comment cela fonctionne. Il est écrit en utilisant __proto__
ce qui n'est pas standard et, par conséquent, je ne le recommande pas .
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;
}
Remarque : j'ai écrit ceci, par curiosité, et il n'est écrit qu'en termes simples, par exemple, je ne transfère pas les descripteurs de propriété du deuxième objet à l'objet de retour.
__proto__
fera désormais officiellement partie du langage.
-1
en arguments.length>0?arguments[0]:-1;
?
Object
prototype soit conservé si le premier argument n'est pas donné. Les noms de variables pourraient être bien meilleurs ici.
Lorsque vous créez un objet avec Object.create (null), cela signifie que vous créez un objet sans prototype. null signifie ici la fin de la chaîne de prototypes. Néanmoins, lorsque vous créez un objet comme {} Object prototype sera ajouté. Il s'agit donc de deux objets différents, l'un avec un prototype, l'autre sans prototype.
if (someKey in p) {