07. Freezing Object

Существует три стандартных уровня защиты объекта от изменений:

  • Запрет расширений -- запрещает добавлять в объект новые атрибуты.

  • Seal -- запрещает расширять объект и запрещает настраивать свойства.

  • Freeze -- запрещает расширять, настраивать и изменять значения свойств.

Prevent Extensions

Каждый объект имеет системное поле extensible, которое определяет, допускается ли добавлять в объект новые свойства. Назначение атрибута extensible заключается в том, чтобы дать возможность «фиксировать» объекты в определенном состоянии, запретив внесение изменений. Чтобы определить, допускается ли расширять объект, его следует передать методу Object.isExtensible(). Чтобы сделать объект нерасширяемым, его нужно передать методу Object.preventExtensions().

  • После того как объект будет сделан нерасширяемым, его нельзя снова сделать расширяемым.

  • Вызов preventExtensions() оказывает влияние только на расширяемость самого объекта. Если новые свойства добавить в прототип нерасширяемого объекта, нерасширяемый объект унаследует эти новые свойства.

    -

const obj={foo:'a'};
Object.preventExtensions(obj);

> obj.bar = 'b';
> obj.bar
undefined

В строгом режиме будет ошибка.

Sealing object

Метод Object.seal()/Object.isSealed() действует подобно методу Object.preventExtensions(), но он не только делает объект нерасширяемым, но и делает все свойства этого объекта недоступными для настройки. То есть в объект нельзя будет добавить новые свойства, а существующие свойства нельзя будет удалить или настроить. Однако существующие свойства, доступные для записи, по-прежнему могут быть изменены.

> const obj = { foo: 'a' };
> Object.getOwnPropertyDescriptor(obj, 'foo')  // before sealing
{ value: 'a', writable: true, enumerable: true, configurable: true }

> Object.seal(obj)
> Object.getOwnPropertyDescriptor(obj, 'foo')  // after sealing
{ value: 'a', writable: true, enumerable: true, configurable: false }

Freezing object

Метод Object.freeze()/Object.isFrozen() делает объект нерасширяемым, а его свойства недоступными для настройки, он также делает все собственные свойства с данными доступными только для чтения.

const point={x: 17, y: -5};
Object.freeze(point);

> point.x = 2; // no effect, point.x is read-only
> point.x
17
> point.z = 123; // no effect, point is not extensible
> point
{ x: 17, y: -5 }

В строгом режиме попытки нарушить защиту объекта приведут к выбросу исключения.

Важно понимать, что Object.seal() и Object.freeze() воздействуют только на объект, который им передается: они не затрагивают прототип этого объекта. Если в программе потребуется полностью зафиксировать объект, вам, вероятно, потребуется зафиксировать также объекты в цепочке прототипов. Более того, заморозка объекта является "поверхностной" в том смысле, что замораживая объект -- не замораживаются изменяемые свойства; изменяемые свойства по-прежнему можно полностью изменять.

Last updated