Object.freeze - garevna/js-course GitHub Wiki
• Object.assign()
• Object.create()
• Object.defineProperty()
• Object.defineProperties()
• Object.entries()
Числа, строки и булевы значения в 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()