← Назад к вопросам
В чем разница между Object.keys и Object.getOwnPropertyNames?
2.0 Middle🔥 133 комментариев
#JavaScript Core
Комментарии (3)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между Object.keys и Object.getOwnPropertyNames
Object.keys и Object.getOwnPropertyNames — это два похожих метода для получения свойств объекта, но они работают по-разному. Основное отличие в том, какие свойства они возвращают.
Object.keys
Object.keys() возвращает массив только перечисляемых собственных свойств объекта. Это свойства, которые видны в цикле for...in и помечены как enumerable: true.
const user = {
name: "Иван",
age: 25,
email: "ivan@mail.com"
};
const keys = Object.keys(user);
console.log(keys); // ["name", "age", "email"]
Object.getOwnPropertyNames
Object.getOwnPropertyNames() возвращает массив всех собственных свойств, включая неперечисляемые. Но не включает символы.
const user = {};
// Создаем перечисляемое свойство (по умолчанию)
Object.defineProperty(user, "name", {
value: "Иван",
enumerable: true
});
// Создаем неперечисляемое свойство
Object.defineProperty(user, "password", {
value: "secret123",
enumerable: false
});
const keys = Object.keys(user);
console.log(keys); // ["name"] - только перечисляемые
const allKeys = Object.getOwnPropertyNames(user);
console.log(allKeys); // ["name", "password"] - все свойства
Практический пример 1: Обычный объект
const person = {
firstName: "Иван",
lastName: "Петров",
age: 25
};
// Object.keys
console.log(Object.keys(person));
// ["firstName", "lastName", "age"]
// Object.getOwnPropertyNames
console.log(Object.getOwnPropertyNames(person));
// ["firstName", "lastName", "age"]
// В этом случае результаты одинаковые, потому что все свойства перечисляемые
Практический пример 2: Объект с неперечисляемыми свойствами
const obj = {
visible: "видно"
};
// Добавляем неперечисляемое свойство
Object.defineProperty(obj, "hidden", {
value: "не видно",
enumerable: false // неперечисляемо
});
console.log(Object.keys(obj));
// ["visible"] - видны только перечисляемые
console.log(Object.getOwnPropertyNames(obj));
// ["visible", "hidden"] - видны все
Практический пример 3: Класс с методами
class User {
constructor(name) {
this.name = name;
}
greet() {
console.log("Привет, я " + this.name);
}
}
const user = new User("Иван");
console.log(Object.keys(user));
// ["name"] - только собственные свойства экземпляра
console.log(Object.getOwnPropertyNames(user));
// ["name"] - то же, что keys (name перечисляемо)
console.log(Object.getOwnPropertyNames(User.prototype));
// ["constructor", "greet"] - методы класса (не перечисляемы по умолчанию)
Сравнительная таблица
| Метод | Перечисляемые | Неперечисляемые | Символы | Унаследованные |
|---|---|---|---|---|
| Object.keys | ДА | НЕТ | НЕТ | НЕТ |
| Object.getOwnPropertyNames | ДА | ДА | НЕТ | НЕТ |
| for...in | ДА | НЕТ | НЕТ | ДА |
| Object.getOwnPropertySymbols | - | - | ДА | НЕТ |
Практический пример 4: Приватные данные
const obj = {
publicData: "видимо всем"
};
// Приватные данные (неперечисляемые)
Object.defineProperty(obj, "_privateData", {
value: "только для использования внутри",
enumerable: false
});
console.log(Object.keys(obj));
// ["publicData"]
console.log(Object.getOwnPropertyNames(obj));
// ["publicData", "_privateData"]
// Доступ все равно возможен
console.log(obj._privateData); // "только для использования внутри"
Практический пример 5: Копирование объекта
const original = {};
Object.defineProperty(original, "visible", {
value: "видно",
enumerable: true
});
Object.defineProperty(original, "hidden", {
value: "не видно",
enumerable: false
});
// Копирование только перечисляемых (неправильно!)
const copy1 = {};
Object.keys(original).forEach(key => {
copy1[key] = original[key];
});
console.log(copy1); // { visible: "видно" } - потеряется hidden
// Копирование всех свойств (правильно!)
const copy2 = {};
Object.getOwnPropertyNames(original).forEach(key => {
copy2[key] = original[key];
});
console.log(copy2); // { visible: "видно", hidden: "не видно" }
// Или использовать Object.assign (копирует перечисляемые)
const copy3 = Object.assign({}, original);
console.log(copy3); // { visible: "видно" }
Практический пример 6: Итерирование по свойствам
const user = {
name: "Иван",
email: "ivan@mail.com"
};
// Скрытое свойство
Object.defineProperty(user, "_id", {
value: 123,
enumerable: false
});
// Способ 1: Object.keys (только видимые)
Object.keys(user).forEach(key => {
console.log(`${key}: ${user[key]}`);
});
// name: Иван
// email: ivan@mail.com
// Способ 2: Object.getOwnPropertyNames (все)
Object.getOwnPropertyNames(user).forEach(key => {
console.log(`${key}: ${user[key]}`);
});
// name: Иван
// email: ivan@mail.com
// _id: 123
// Способ 3: for...in (видимые и унаследованные)
for (let key in user) {
console.log(`${key}: ${user[key]}`);
}
// name: Иван
// email: ivan@mail.com
Практический пример 7: Символы
const obj = {
name: "Иван"
};
const sym = Symbol("id");
obj[sym] = 123;
console.log(Object.keys(obj));
// ["name"] - символы не включаются
console.log(Object.getOwnPropertyNames(obj));
// ["name"] - символы не включаются
console.log(Object.getOwnPropertySymbols(obj));
// [Symbol(id)] - отдельный метод для символов
Когда использовать какой метод
Object.keys():
- Когда нужны только перечисляемые свойства
- Для сериализации объекта в JSON
- Для обычного итерирования по видимым свойствам
- Это более "безопасный" вариант
const user = { name: "Иван", age: 25 };
const json = JSON.stringify(Object.keys(user)); // "[\"name\",\"age\"]"
Object.getOwnPropertyNames():
- Когда нужны все свойства, включая скрытые
- При работе с приватными данными
- При полном копировании объекта
- При анализе структуры объекта
const obj = { visible: "да" };
Object.defineProperty(obj, "hidden", { value: "скрыто", enumerable: false });
// Получить ВСЕ свойства
const allKeys = Object.getOwnPropertyNames(obj); // ["visible", "hidden"]
Совет: Получить все (включая символы)
function getAllProperties(obj) {
const keys = Object.getOwnPropertyNames(obj);
const symbols = Object.getOwnPropertySymbols(obj);
return [...keys, ...symbols];
}
const obj = { name: "Иван" };
const sym = Symbol("id");
obj[sym] = 123;
console.log(getAllProperties(obj));
// ["name", Symbol(id)]
Ключевые выводы
- Object.keys() возвращает только перечисляемые свойства
- Object.getOwnPropertyNames() возвращает все свойства (кроме символов)
- Оба метода возвращают только собственные свойства объекта (не унаследованные)
- Для символов используйте Object.getOwnPropertySymbols()
- for...in возвращает перечисляемые свойства, включая унаследованные