Object.freeze - garevna/js-course GitHub Wiki

🎓 Статические методы конструктора Object

Object.assign()
Object.create()
Object.defineProperty()
Object.defineProperties()
Object.entries()


🎓 Object.freeze

Числа, строки и булевы значения в JS неиммутабельны, т.е. их значения не меняются при операциях с ними, но каждый раз возвращается новое значение

1

var string = "Welcome to JS!"

string.split ( " " ) // [ "Welcome", "to", "JS!" ]

console.log ( string ) // "Welcome to JS!"

Объекты и массивы JS по природе своей иммутабельны ( изменяемы )

2

var food = [ "milk", "apple", "soup" ]

food.push ( "meat" )

console.log ( food ) // [ "milk", "apple", "soup", "meat" ]

Мы легко добавляем новые свойства объекту:

3

var provider = { name: "Google" }

provider.addProp = function ( propName, propVal ) {
    this[ propName ] = propVal
}

provider.addProp ( "browser", "Chrome" )

console.log ( provider ) // { name: "Google", browser: "Chrome" }

Метод Object.freeze делает объект неиммутабельным, т.е. предотвращает:

📌 добавление новых свойств к объекту

4

var provider = { name: "Google" }

Object.freeze ( provider )

provider.addProp = function ( propName, propVal ) {
    this[ propName ] = propVal
}

console.log ( provider ) // { name: "Google" }

📌 удаление свойств объекта

5

var provider = { name: "Google", service: "API" }

Object.freeze ( provider )

delete provider.service  // false

console.log ( provider ) // { name: "Google", service: "API" }

📌 изменение существующих свойств объекта

6

var provider = { name: "Google", service: "API" }

Object.freeze ( provider )

provider.name = "Mozilla"

console.log ( provider.name ) // Google

📌 изменение дескрипторов свойств объекта ( значений enumerable, configurable и writable )

7

Изменим дескриптор свойства объекта до "заморозки":

var provider = { name: "Google", service: "API" }

Object.defineProperty ( provider, "name", {
    enumerable: false,
    writable: false
} )

for ( var prop in provider )
    console.log ( `${prop}: ${provider [ prop ]}` )

// service: API

Как видите, свойство name стало неперечислимым

Проверим, изменяемо ли оно:

provider.name = "Mozilla"

console.log ( provider.name ) // "Google"

Теперь опять изменим дескриптор свойства name и изменим его значение:

Object.defineProperty ( provider, "name", {
    enumerable: true,
    writable: true
} )

provider.name = "Mozilla"

Выведем все перечислимые свойства объекта:

for ( var prop in provider )
    console.log ( `${prop}: ${provider [ prop ]}` )

// name: Mozilla
// service: API

Т.е. мы опять сделали свойство name перечислимым

А теперь "заморозим" объект и попробуем переконфигурировать свойство service

Object.freeze ( provider )

Object.defineProperty ( provider, "service", {
    enumerable: false,
    writable: false
} )

⛔ Будет сгенерировано исключение:

Uncaught TypeError: Cannot redefine property: service

Однако изменить значение свойства service мы не сможем, хотя нам и не удалось изменить дескриптор этого свойства

Почему? Заглянем теперь в дескриптор:

Object.getOwnPropertyDescriptor ( provider, "service" )

// { value: "API", writable: false, enumerable: true, configurable: false }

Т.е. в результате "заморозки" объекта дескрипторы его свойств были автоматически изменены: свойства стали неизменяемы и не конфигурируемы

Единственное, что "не зацепила" заморозка объекта - это атрибут enumerable

Если мы сами не установим его значение в false перед заморозкой, то свойства будут перечислимыми


Object.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptors()
Object.getOwnPropertyNames()
• Object.getOwnPropertySymbols()
• Object.getPrototypeOf()
• Object.is()
• Object.isExtensible()
• Object.isFrozen()
• Object.isSealed()
Object.keys()
• Object.preventExtensions()
• Object.seal()
• Object.setPrototypeOf()
Object.values()


⚠️ **GitHub.com Fallback** ⚠️