# 07. Freezing Object

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

* **Запрет расширений** -- запрещает добавлять в объект новые атрибуты.
* **Seal** -- запрещает расширять объект и запрещает настраивать свойства.
* **Freeze** -- запрещает расширять, настраивать и изменять значения свойств.

## Prevent Extensions

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

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

    \-

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

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

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

## Sealing object

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

```javascript
> 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()` делает объект нерасширяемым, а его свойства недоступными для настройки, он также делает все собственные свойства с данными доступными только для чтения.

```javascript
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()` воздействуют только на объект, который им передается: они не затрагивают прототип этого объекта. Если в программе потребуется полностью зафиксировать объект, вам, вероятно, потребуется зафиксировать также объекты в цепочке прототипов. Более того, заморозка объекта является "поверхностной" в том смысле, что замораживая объект -- не замораживаются изменяемые свойства; изменяемые свойства по-прежнему можно полностью изменять.
