Qual é a diferença entre Object.getOwnPropertyNames
e Object.keys
em javascript? Também alguns exemplos seriam apreciados.
Qual é a diferença entre Object.getOwnPropertyNames
e Object.keys
em javascript? Também alguns exemplos seriam apreciados.
Respostas:
Há uma pequena diferença. Object.getOwnPropertyNames(a)
retorna todas as próprias propriedades do objeto a
. Object.keys(a)
retorna todos os enumeráveis propriedades próprias . Isso significa que, se você definir suas propriedades de objeto sem criar algumas delas, enumerable: false
esses dois métodos fornecerão o mesmo resultado.
É fácil testar:
var a = {};
Object.defineProperties(a, {
one: {enumerable: true, value: 'one'},
two: {enumerable: false, value: 'two'},
});
Object.keys(a); // ["one"]
Object.getOwnPropertyNames(a); // ["one", "two"]
Se você definir uma propriedade sem fornecer o descritor de atributos de propriedade (o que significa que você não usa Object.defineProperties
), por exemplo:
a.test = 21;
então essa propriedade se torna um enumerável automaticamente e os dois métodos produzem a mesma matriz.
length
propriedades dos objetos de matriz não são enumeráveis, portanto, elas não aparecem Object.keys
.
length
propriedade dos objetos está no protótipo, não no próprio objeto, portanto, Object.keys
nem Object.getOwnPropertyNames
o listará.
Object.getOwnPropertyNames(anyArray)
includeslength
Object.getOwnPropertyNames(anyArray)
de fato inclui length
na matriz retornada!
Notação literal versus construtor ao criar um objeto. Aqui está algo que me pegou.
const cat1 = {
eat() {},
sleep() {},
talk() {}
};
// here the methods will be part of the Cat Prototype
class Cat {
eat() {}
sleep() {}
talk() {}
}
const cat2 = new Cat()
Object.keys(cat1) // ["eat", "sleep", "talk"]
Object.keys(Object.getPrototypeOf(cat2)) // []
Object.getOwnPropertyNames(cat1) // ["eat", "sleep", "talk"]
Object.getOwnPropertyNames(Object.getPrototypeOf(cat2)) // ["eat", "sleep", "talk"]
cat1 // {eat: function, sleep: function, talk: function}
cat2 // Cat {}
// a partial of a function that is used to do some magic redeclaration of props
function foo(Obj) {
var propNames = Object.keys(Obj);
// I was missing this if
// if (propNames.length === 0) {
// propNames = Object.getOwnPropertyNames(Obj);
// }
for (var prop in propNames) {
var propName = propNames[prop];
APIObject[propName] = "reasign/redefine or sth";
}
}
Então, no meu caso, o foo
função não funcionaria se eu desse objetos do tipo cat2.
Existem outras maneiras de criar objetos, portanto também pode haver outras distorções.
Object.getOwnPropertyNames
retornará os nomes de propriedades para cat1
e não cat2
. As duas maneiras de criar o objeto não produzem diferença entre Object.getOwnPropertyNames
e Object.keys
.
Como já foi explicado, .keys
não retorna propriedades enumeráveis.
Em relação aos exemplos, um dos casos de armadilha é um Error
objeto: algumas de suas propriedades são enumeráveis.
Então, enquanto console.log(Object.keys(new Error('some msg')))
produz []
,
console.log(Object.getOwnPropertyNames(new Error('some msg')))
produz["stack", "message"]
console.log(Object.keys(new Error('some msg')));
console.log(Object.getOwnPropertyNames(new Error('some msg')));
Outra diferença é que (pelo menos com nodejs) a função "getOwnPropertyNames" não garante a ordem das chaves, é por isso que geralmente uso a função "keys":
Object.keys(o).forEach(function(k) {
if (!o.propertyIsEnumerable(k)) return;
// do something...
});
getOwnPropertyNames
não estar em ordem? Porque o ES2015 especifica um pedido paraObect.getOwnPropertyNames
, enquanto o pedidoObect.keys
ainda depende da implementação.
for-in loop
, Object.keys
, e Object.getOwnPropertyNames
. Dito isto, os três serão enumerados em uma ordem consistente em relação um ao outro.
Object.keys()
não as retorna, enquanto oObject.getOwnPropertyNames()
faz.