Object.getOwnPropertyDescriptor() возвращает дескриптор свойства объекта.
Этот метод полезен, когда нужно посмотреть не только значение свойства, но и его настройки:
- можно ли его менять
- видно ли оно в перечислении
- можно ли его перенастраивать
- является ли оно геттером или сеттером
Синтаксис
Object.getOwnPropertyDescriptor(obj, propertyName)
obj - объект, у которого нужно посмотреть свойство.
propertyName - имя свойства.
Что делает Object.getOwnPropertyDescriptor()
Метод возвращает объект с описанием свойства.
const user = {
name: "Anna",
};
console.log(Object.getOwnPropertyDescriptor(user, "name"));
Результат будет примерно таким:
{
value: "Anna",
writable: true,
enumerable: true,
configurable: true
}
Что возвращает метод
Если свойство существует и принадлежит самому объекту, метод вернёт объект-дескриптор.
Если такого собственного свойства нет, результатом будет undefined.
const user = { name: "Anna" };
console.log(Object.getOwnPropertyDescriptor(user, "name"));
// { value: "Anna", writable: true, enumerable: true, configurable: true }
console.log(Object.getOwnPropertyDescriptor(user, "age")); // undefined
Только собственные свойства
Это важный момент.
Метод не смотрит в прототип.
const base = { role: "user" };
const person = Object.create(base);
person.name = "Anna";
console.log(Object.getOwnPropertyDescriptor(person, "name"));
// дескриптор свойства name
console.log(Object.getOwnPropertyDescriptor(person, "role")); // undefined
Хотя person.role доступно, это свойство унаследовано, а не принадлежит самому объекту.
Обычное свойство: value, writable, enumerable, configurable
Для обычного свойства дескриптор обычно содержит такие поля:
value- само значениеwritable- можно ли менять значениеenumerable- участвует ли свойство в перечисленииconfigurable- можно ли его перенастраивать или удалять
Пример:
const user = { name: "Anna" };
const descriptor = Object.getOwnPropertyDescriptor(user, "name");
console.log(descriptor.value); // "Anna"
console.log(descriptor.writable); // true
console.log(descriptor.enumerable); // true
console.log(descriptor.configurable); // true
Неперечисляемое свойство
Через Object.defineProperty() можно создать свойство с другими настройками.
const user = {};
Object.defineProperty(user, "secret", {
value: "123",
enumerable: false,
});
console.log(Object.getOwnPropertyDescriptor(user, "secret"));
Здесь в дескрипторе будет видно, что enumerable равно false.
Геттеры и сеттеры
Если свойство устроено через getter/setter, дескриптор будет другим.
const user = {
firstName: "Anna",
lastName: "Smith",
get fullName() {
return `${this.firstName} ${this.lastName}`;
},
};
console.log(Object.getOwnPropertyDescriptor(user, "fullName"));
В этом случае вместо value и writable в дескрипторе обычно будут:
getsetenumerableconfigurable
То есть метод помогает увидеть, что перед нами не обычное свойство, а accessor property.
Object.getOwnPropertyDescriptor() не меняет объект
Метод только читает информацию о свойстве и ничего не изменяет.
const user = { name: "Anna" };
const descriptor = Object.getOwnPropertyDescriptor(user, "name");
console.log(user); // { name: "Anna" }
console.log(descriptor); // объект-дескриптор
Массивы тоже работают
Массив - это тоже объект, поэтому метод работает и с ним.
const arr = ["a", "b"];
console.log(Object.getOwnPropertyDescriptor(arr, "0"));
// { value: "a", writable: true, enumerable: true, configurable: true }
Интересный пример - length:
const arr = ["a", "b"];
console.log(Object.getOwnPropertyDescriptor(arr, "length"));
У length будут свои настройки, и это хороший способ увидеть, что свойство устроено не совсем как обычный индекс массива.
Символьные ключи
Метод умеет работать и с ключами-символами.
const id = Symbol("id");
const user = {
[id]: 1,
};
console.log(Object.getOwnPropertyDescriptor(user, id));
Object.getOwnPropertyDescriptor() и Object.defineProperty()
Эти методы часто используют рядом:
Object.getOwnPropertyDescriptor()читает дескрипторObject.defineProperty()создаёт или настраивает свойство
const user = { name: "Anna" };
const descriptor = Object.getOwnPropertyDescriptor(user, "name");
console.log(descriptor.enumerable); // true
То есть один метод помогает посмотреть настройки, а второй - изменить их.
Object.getOwnPropertyDescriptor() и Object.keys()
Object.keys() показывает только перечисляемые собственные ключи.
Object.getOwnPropertyDescriptor() позволяет понять, почему свойство попадает или не попадает в это перечисление.
const user = {};
Object.defineProperty(user, "secret", {
value: "123",
enumerable: false,
});
console.log(Object.keys(user)); // []
console.log(Object.getOwnPropertyDescriptor(user, "secret").enumerable); // false
Когда это полезно
Object.getOwnPropertyDescriptor() удобно использовать, когда:
- нужно понять, почему свойство ведёт себя определённым образом
- нужно проверить
writable,enumerableилиconfigurable - нужно разобраться, является ли свойство геттером/сеттером
- вы работаете с
Object.defineProperty()
Частые ошибки
Думать, что метод ищет свойства в прототипе
const base = { role: "user" };
const person = Object.create(base);
console.log(Object.getOwnPropertyDescriptor(person, "role")); // undefined
Метод смотрит только на собственные свойства объекта.
Ждать, что всегда будет поле value
const user = {
get name() {
return "Anna";
},
};
console.log(Object.getOwnPropertyDescriptor(user, "name"));
Для геттера/сеттера структура дескриптора будет другой.
Путать значение свойства и дескриптор
const user = { name: "Anna" };
console.log(user.name); // "Anna"
console.log(Object.getOwnPropertyDescriptor(user, "name"));
// объект с настройками свойства
Метод возвращает не само значение, а описание свойства.
Быстрая памятка
Object.getOwnPropertyDescriptor()возвращает дескриптор собственного свойства- если свойства нет, результатом будет
undefined - метод не смотрит в прототип
- для обычных свойств важны
value,writable,enumerable,configurable - для getter/setter дескриптор будет другим
Коротко
Object.getOwnPropertyDescriptor() - это способ посмотреть внутренние настройки свойства объекта. Главное, что стоит запомнить: метод возвращает не значение, а дескриптор свойства, и помогает понять, можно ли это свойство менять, перечислять или перенастраивать.