05. Property Attributes
Помимо имени и значения, свойства обладают атрибутами, определяющие их характеристики. Атрибуты, имеющиеся у всех свойств:
Признак доступности для перечисления (
enumerable
). Еслиtrue
, то свойство просматривается в циклеfor..in
и методеObject.keys()
.Признак доступности для настройки (
configurable
) контролирует попытки изменить другие атрибуты (а также определяет возможность удаления свойства).Если
false
, то никакие другие атрибуты свойства кромеvalue
менять нельзя.Если
true
, то свойство можно удалять, а также менять его в дальнейшем при помощи новых вызововdefineProperty
. Для такого свойства нельзя изменить его атрибутыconfigurable
иenumerable
, а так же нельзя изменить значение его атрибутаwritable
сfalse
наtrue
, но его можно изменить сtrue
наfalse
.
Значение (
value
) - значение по ключу.Признак доступности для записи (
writable
) контролирует попытки изменить атрибутvalue
. Значение свойства можно менять, еслиtrue
. По умолчаниюfalse
.
const c = { key: "value" };
Object.getOwnPropertyDescriptor(c, "key"); // => {value: "value", writable: true, enumerable: true, configurable: true}
Если свойство с данными недоступно для настройки и для записи, нельзя изменить его значение. Однако изменить значение свойства, недоступного для записи можно, если оно доступно для настройки (потому что свойство можно сделать доступным для записи, изменить его значение и затем опять сделать свойство доступным только для чтения).
Property attributes for get
/set
properties
get
/set
propertiesВ свойствах с методами доступа (get/set
-функции) отсутствуют атрибуты value
и writable
: их доступность для записи определяется наличием или отсутствием метода записи. Поэтому четырьмя атрибутами свойств с методами доступа являются: метод чтения (get
), метод записи (set
), признак доступности для перечисления (enumerable
) и признак доступности для настройки (configurable
). Если свойство с методами доступа недоступно для настройки, нельзя изменить его методы чтения и записи и нельзя превратить его в простое свойство с данными.
Access to property attributes
Получить дескриптор свойства требуемого объекта можно вызовом Object.getOwnPropertyDescriptor()
, который работает только с собственными свойствами. Чтобы получить атрибуты унаследованного свойства, необходимо явно выполнить обход цепочки прототипов.
Object.getOwnPropertyDescriptor({ x: 1 }, "x"); // => {value: 1, writable:true, enumerable:true, configurable:true}
Метод Object.getOwnPropertyDescriptors(obj)
вернет объект с теми же ключами, а значениями будут дескрипторы свойств ключей объекта.
const obj = {
get bar() {
return "abc";
}
};
console.log(Object.getOwnPropertyDescriptors(obj));
// Output:
// { [Symbol('foo')]:
// { value: 123,
// writable: true,
// enumerable: true,
// configurable: true },
// bar:
// { get: [Function: bar],
// set: undefined,
// enumerable: true,
// configurable: true } }
Чтобы изменить значение атрибута свойства или создать новое свойство с заданными значениями атрибутов, следует вызвать метод Object.defineProperty()
, передав ему объект, в котором требуется выполнить изменения, имя создаваемого или изменяемого свойства и объект дескриптора свойства. Дескриптор свойства, необязательно должен иметь все четыре атрибута.
const o = {};
Object.defineProperty(o, "x", {
value: 1,
writable: true,
enumerable: false,
configurable: true
});
Если возникнет необходимость создать или изменить сразу несколько свойств, можно воспользоваться методом Object.defineProperties()
. Первым аргументом ему передается объект, который требуется изменить. Вторым аргументом – объект, отображающий имена создаваемых или модифицируемых свойств в дескрипторы этих свойств.
const p = Object.defineProperties(
{},
{
x: { value: 1, writable: true, enumerable: true, configurable: true },
y: { value: 1, writable: true, enumerable: true, configurable: true },
r: {
get: function() {
return Math.sqrt(this.x * this.x + this.y * this.y);
},
enumerable: true,
configurable: true
}
}
);
Методы Object.defineProperty()
и Object.defineProperties()
возбуждают исключение TypeError
, когда создание или изменение свойств запрещено. Например, при попытке добавить новое свойство в нерасширяемый объект.
Receipts
Примеры и паттерны использования:
Constant attribute
Object.defineProperty(user, "name", {
value: "Anton",
writable: false, // запретить присвоение "user.name="
configurable: false // запретить удаление "delete user.name"
});
Non enumerable attribute
Object.defineProperty(user, "name", {
value: "Anton",
enumerable: false // запретить перебор свойства
});
Last updated
Was this helpful?