¿Cuál es la diferencia entre Object.getOwnPropertyNamesy Object.keysen JavaScript? También se agradecerían algunos ejemplos.
¿Cuál es la diferencia entre Object.getOwnPropertyNamesy Object.keysen JavaScript? También se agradecerían algunos ejemplos.
Respuestas:
Hay una pequeña diferencia Object.getOwnPropertyNames(a)devuelve todas las propiedades propias del objeto a. Object.keys(a)devuelve todas las propiedades propias enumerables . Significa que si define las propiedades de su objeto sin hacer algunas de ellas, enumerable: falseestos dos métodos le darán el mismo resultado.
Es fácil de probar:
var a = {};
Object.defineProperties(a, {
one: {enumerable: true, value: 'one'},
two: {enumerable: false, value: 'two'},
});
Object.keys(a); // ["one"]
Object.getOwnPropertyNames(a); // ["one", "two"]
Si define una propiedad sin proporcionar un descriptor de atributos de propiedad (lo que significa que no usa Object.defineProperties), por ejemplo:
a.test = 21;
entonces dicha propiedad se convierte automáticamente en enumerable y ambos métodos producen la misma matriz.
lengthpropiedades de los objetos de matriz no son enumerables, por lo que no se muestran en Object.keys.
lengthpropiedad de los objetos está en el prototipo, no en el objeto en sí, por lo que Object.keysni Object.getOwnPropertyNameslo enumerará.
Object.getOwnPropertyNames(anyArray)incluyelength
Object.getOwnPropertyNames(anyArray)de hecho incluye lengthen la matriz devuelta!
Notación literal vs constructor al crear objeto. Aquí hay algo que me atrapó.
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";
}
}
Entonces, en mi caso, la foofunción no funcionó si le di objetos del tipo cat2.
Hay otras formas de crear objetos, por lo que también podría haber otros problemas.
Object.getOwnPropertyNamesdevolverá los nombres de propiedad para cat1y no cat2. Las dos formas de crear el objeto no producen una diferencia entre Object.getOwnPropertyNamesy Object.keys.
Como ya se explicó, .keysno devuelve propiedades enumerables.
En cuanto a los ejemplos, uno de los casos de dificultades es un Errorobjeto: algunas de sus propiedades son enumerables.
Entonces, mientras console.log(Object.keys(new Error('some msg')))rinde [],
console.log(Object.getOwnPropertyNames(new Error('some msg')))rinde["stack", "message"]
console.log(Object.keys(new Error('some msg')));
console.log(Object.getOwnPropertyNames(new Error('some msg')));
Otra diferencia es que (al menos con nodejs) la función "getOwnPropertyNames" no garantiza el orden de las claves, es por eso que generalmente uso la función "claves":
Object.keys(o).forEach(function(k) {
if (!o.propertyIsEnumerable(k)) return;
// do something...
});
getOwnPropertyNamesno estar en orden? Porque ES2015 especifica un pedido paraObect.getOwnPropertyNames , mientras que el pedidoObect.keys aún depende de la implementación.
for-in loop, Object.keys, y Object.getOwnPropertyNames. Dicho esto, los tres se enumerarán en un orden consistente uno con respecto al otro.
Object.keys()no las devuelve, mientras queObject.getOwnPropertyNames()sí.