Conheço várias maneiras de criar objetos JS, mas não sabia qual Object.create(null)deles.
Questão:
é exatamente o mesmo que:
var p = {}
vs
var p2 = Object.create(null);
?
Conheço várias maneiras de criar objetos JS, mas não sabia qual Object.create(null)deles.
Questão:
é exatamente o mesmo que:
var p = {}
vs
var p2 = Object.create(null);
?
Respostas:
Eles não são equivalentes. {}.constructor.prototype == Object.prototypeenquanto Object.create(null)não herda de nada e, portanto, não possui propriedades.
Em outras palavras: herda javascript objeto a de objeto por padrão, a menos que explicitamente criar-lo com nulo como seu protótipo, como: Object.create(null).
{}seria equivalente a Object.create(Object.prototype).
No Chrome Devtool, você pode ver que Object.create(null)não tem __proto__propriedade, enquanto o {}faz.
Definitivamente, eles não são equivalentes. Estou escrevendo esta resposta para explicar melhor por que isso faz a diferença.
var p = {};
Cria um objeto que herda as propriedades e métodos de Object.
var p2 = Object.create(null);
Cria um objeto que não herda nada.
Se você estiver usando um objeto como um mapa e criar um objeto usando o método 1 acima, precisará ter um cuidado extra ao fazer pesquisas no mapa. Como as propriedades e métodos de Objectsão herdados, seu código pode ser executado em um caso em que existem chaves no mapa que você nunca inseriu. Por exemplo, se você fizesse uma pesquisa toString, encontraria uma função, mesmo que nunca coloque esse valor lá. Você pode contornar isso assim:
if (Object.prototype.hasOwnProperty.call(p, 'toString')) {
// we actually inserted a 'toString' key into p
}
Observe que não há problema em atribuir algo p.toString, ele simplesmente substituirá a toStringfunção herdada p.
Observe que você não pode simplesmente fazer isso p.hasOwnProperty('toString')porque pode ter inserido uma chave "hasOwnProperty" em p, portanto forçamos que ela use a implementação no Object.
Por outro lado, se você usar o método 2 acima, não precisará se preocupar com o fato de as coisas Objectaparecerem no mapa.
Você não pode verificar a existência de uma propriedade com um simples ifcomo este:
// Unreliable:
if (p[someKey]) {
// ...
}
O valor pode ser uma sequência vazia, pode ser false, ou null, ou undefined, ou 0, ou NaN, etc. Para verificar se existe uma propriedade, você ainda precisará usar Object.prototype.hasOwnProperty.call(p, someKey).
Object.create(null). Prefiro não fazer suposições como essa, mesmo que você estivesse absolutamente certo de que era usado Object.create(null), o código poderia mudar, o objeto poderia ser substituído por um que herda Objectem algum momento. hasOwnPropertysempre funciona.
{}é muito mais prevalente que Object.create(null), se o seu código acidentalmente pegar uma propriedade herdada nesse momento, você provavelmente terá bugs muito maiores para se preocupar. Só consigo ver pessoas usando Object.create (null) como uma otimização menor.
!!p[key]funciona bem com Object.create(null). Mas hasKey = (key, input) => Object.prototype.hasOwnProperty.call(input, key)também não é ruim
pporque todos os métodos podem ser inseridos e, portanto, não se tornam seguros.
Criar objetos usando {}criará um objeto cujo protótipo é o Object.prototypeque herda as funções básicas do Objectprotótipo enquanto cria objetos usando Object.create(null)criará um objeto vazio cujo protótipo é nulo.
Se alguém está procurando implementar Object.create(null), apenas para saber como funciona. É escrito usando o __proto__que não é padrão e, portanto, eu não o recomendo .
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 : escrevi isso por curiosidade e é escrito apenas em termos simples, por exemplo, não estou transferindo os descritores de propriedade do segundo objeto para o objeto de retorno.
__proto__agora será oficialmente parte do idioma.
-1dentro arguments.length>0?arguments[0]:-1;?
Objectprotótipo seja retido se o primeiro argumento não for fornecido. Nomes de variáveis podem ser muito melhores aqui.
Quando você cria um Objeto com Object.create (null), isso significa que você está criando um Objeto sem protótipo. null aqui significa o fim da cadeia de protótipos. No entanto, quando você criar um objeto como {}, o protótipo de objeto será adicionado. Portanto, esses são dois objetos diferentes, um com protótipo e outro sem protótipo.
if (someKey in p) {