Qual é a diferença entre Object.getOwnPropertyNamese Object.keysem javascript? Também alguns exemplos seriam apreciados.
Qual é a diferença entre Object.getOwnPropertyNamese Object.keysem 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: falseesses 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.
lengthpropriedades dos objetos de matriz não são enumeráveis, portanto, elas não aparecem Object.keys.
lengthpropriedade dos objetos está no protótipo, não no próprio objeto, portanto, Object.keysnem Object.getOwnPropertyNameso listará.
Object.getOwnPropertyNames(anyArray)includeslength
Object.getOwnPropertyNames(anyArray)de fato inclui lengthna 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.getOwnPropertyNamesretornará os nomes de propriedades para cat1e não cat2. As duas maneiras de criar o objeto não produzem diferença entre Object.getOwnPropertyNamese Object.keys.
Como já foi explicado, .keys não retorna propriedades enumeráveis.
Em relação aos exemplos, um dos casos de armadilha é um Errorobjeto: 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...
});
getOwnPropertyNamesnã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.