Какая разница между Object.getOwnPropertyNamesи Object.keysв JavaScript? Также некоторые примеры будут оценены.
Какая разница между Object.getOwnPropertyNamesи Object.keysв JavaScript? Также некоторые примеры будут оценены.
Ответы:
Есть небольшая разница. Object.getOwnPropertyNames(a)возвращает все собственные свойства объекта a. Object.keys(a)возвращает все перечисляемые собственные свойства. Это означает, что если вы определяете свойства вашего объекта, не создавая некоторые из них, enumerable: falseэти два метода дадут вам одинаковый результат.
Это легко проверить:
var a = {};
Object.defineProperties(a, {
one: {enumerable: true, value: 'one'},
two: {enumerable: false, value: 'two'},
});
Object.keys(a); // ["one"]
Object.getOwnPropertyNames(a); // ["one", "two"]
Если вы определяете свойство без предоставления дескриптора атрибутов свойства (то есть не используете Object.defineProperties), например:
a.test = 21;
тогда такое свойство автоматически становится перечислимым, и оба метода создают один и тот же массив.
lengthсвойства объектов массива не перечисляются, поэтому они не отображаются в Object.keys.
lengthСвойство объектов находится на прототипе, а не на самом объекте, поэтому ни перечислять его, Object.keysни Object.getOwnPropertyNamesперечислять не будем.
Object.getOwnPropertyNames(anyArray)включает в себяlength
Object.getOwnPropertyNames(anyArray)действительно включает lengthв возвращаемый массив!
Буквенная нотация против конструктора при создании объекта. Вот то, что меня достало.
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";
}
}
Так что в моем случае fooфункция не сработала, если бы я дал ей объекты типа cat2.
Существуют и другие способы создания объектов, поэтому там могут быть и другие изломы.
Object.getOwnPropertyNamesвернет имена свойств для cat1а не cat2. Два способа создания объекта не дают разницы между Object.getOwnPropertyNamesи Object.keys.
Как уже объяснялось, .keysне возвращает перечислимых свойств.
Что касается примеров, то одним из ловушек является Errorобъект: некоторые его свойства перечислимы.
Так что в то время как console.log(Object.keys(new Error('some msg')))урожайность [],
console.log(Object.getOwnPropertyNames(new Error('some msg')))урожайность["stack", "message"]
console.log(Object.keys(new Error('some msg')));
console.log(Object.getOwnPropertyNames(new Error('some msg')));
Другое отличие состоит в том, что (по крайней мере, для nodejs) функция «getOwnPropertyNames» не гарантирует порядок ключей, поэтому я обычно использую функцию «keys»:
Object.keys(o).forEach(function(k) {
if (!o.propertyIsEnumerable(k)) return;
// do something...
});
getOwnPropertyNamesне в порядке? Потому что ES2015 определяет заказ наObect.getOwnPropertyNames , в то время как заказ наObect.keys все еще до реализации.
for-in loop, Object.keysи Object.getOwnPropertyNames. Тем не менее, все три будут перечислять в последовательном порядке по отношению друг к другу.
Object.keys()не возвращает их, аObject.getOwnPropertyNames()делает.