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);
?
fonte
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);
?
Eles não são equivalentes. {}.constructor.prototype == Object.prototype
enquanto 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 Object
sã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 toString
funçã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 Object
aparecerem no mapa.
Você não pode verificar a existência de uma propriedade com um simples if
como 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)
.
if (someKey in p) {
Object.create(null)
. Prefiro não fazer suposições como essa, mesmo que você estivesse absolutamente certo de que era usadoObject.create(null)
, o código poderia mudar, o objeto poderia ser substituído por um que herdaObject
em algum momento.hasOwnProperty
sempre funciona.{}
é muito mais prevalente queObject.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 comObject.create(null)
. MashasKey = (key, input) => Object.prototype.hasOwnProperty.call(input, key)
também não é ruimp
porque todos os métodos podem ser inseridos e, portanto, não se tornam seguros.Criar objetos usando
{}
criará um objeto cujo protótipo é oObject.prototype
que herda as funções básicas doObject
protótipo enquanto cria objetos usandoObject.create(null)
criará um objeto vazio cujo protótipo é nulo.fonte
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 .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.
fonte
__proto__
agora será oficialmente parte do idioma.-1
dentroarguments.length>0?arguments[0]:-1;
?Object
protó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.
fonte