Яка різниця між 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" не гарантує порядок використання ключів, тому я зазвичай використовую функцію "ключі":
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()робить.