Object.freeze and Object.seal in JS
Object.freeze
prevents any changes to the object. This means that you will not be able to:
Add new properties.
Delete existing properties.
Change the values of existing properties.
Let's look at an example:
const user = {
name: "Artem",
age: 30
};
Object.freeze(user);
// Попытка изменить существующее свойство
user.age = 31; // Без изменений
// Попытка добавить новое свойство
user.email = "alice@example.com"; // Без изменений
console.log(user); // { name: "Artem", age: 30 }
As you can see, all attempts to change the object did not work. On the low Object.freeze
adds a flag non-configurable
to all object properties, which does not allow them to be changed.
If there are nested objects, Object.freeze
does not freeze them automatically. That is, nested properties can still be changed:
const nestedUser = {
name: "Ivan",
address: {
city: "New York"
}
};
Object.freeze(nestedUser);
nestedUser.address.city = "Los Angeles"; // Изменение возможно!
console.log(nestedUser.address.city); // "Los Angeles"
To freeze nested objects, you will have to do it manually or write a recursive function.
Object.seal
Object.seal
allows you to seal an object, which prevents properties from being added or removed, but does not prevent the values of existing properties from being changed.
Let's look at an example:
const settings = {
theme: "light",
notifications: true
};
Object.seal(settings);
// Попытка изменить существующее свойство
settings.theme = "dark"; // Изменение успешно
// Попытка добавить новое свойство
settings.language = "en"; // Без изменений
// Попытка удалить свойство
delete settings.notifications; // Без изменений
console.log(settings); // { theme: "dark", notifications: true }
Change theme
was successful, but we were unable to either add a new property or delete an existing one.
Examples of use
Protecting configuration objects
Configuration objects are those entities that define the behavior of your application. They should be stable and immutable to avoid accidental errors:
const config = {
apiUrl: "https://api.example.com",
timeout: 5000,
retries: 3
};
Object.freeze(config);
// Функция для получения конфигурации
function getConfig() {
return config;
}
// Пример использования
console.log(getConfig().apiUrl); // "https://api.example.com"
// Попытка изменить конфигурацию
config.apiUrl = "https://api.changed.com"; // Не сработает
console.log(getConfig().apiUrl); // Все еще "https://api.example.com"
Using Object.freeze
we guarantee that any attempts to change config
will be ignored/
Use in the Redux library
IN Redux state immutability is the key to predictability and ease of debugging. By using Object.freeze
the state can be protected from unwanted mutations.
Example:
const initialState = {
user: null,
loggedIn: false
};
function reducer(state = initialState, action) {
switch (action.type) {
case 'LOGIN':
return Object.freeze({
...state,
user: action.payload,
loggedIn: true
});
case 'LOGOUT':
return Object.freeze(initialState);
default:
return state;
}
}
Here we use Object.freeze
to make sure that every time the state is updated, it remains the same.
React example
In React, there is often a need to manage the state of components. Protect your status with Object.freeze
can help prevent errors in data mutations.
Example:
import React, { useState } from 'react';
const App = () => {
const [config, setConfig] = useState(Object.freeze({
theme: 'light',
notificationsEnabled: true
}));
const toggleTheme = () => {
// Создаем новый объект вместо изменения существующего
setConfig(prevConfig => Object.freeze({
...prevConfig,
theme: prevConfig.theme === 'light' ? 'dark' : 'light'
}));
};
return (
<div style={{ background: config.theme === 'light' ? '#fff' : '#333' }}>
<h1>Текущая тема: {config.theme}</h1>
<button onClick={toggleTheme}>Сменить тему</button>
</div>
);
};
export default App;
In this example we use Object.freeze
to protect the configuration state.
Protecting Constants and Global Variables
When you work with constants, sometimes you have to ensure that those values aren't accidentally changed. WITHObject.freeze
You can make constants truly immutable.
Example:
const constants = Object.freeze({
MAX_CONNECTIONS: 100,
DEFAULT_TIMEOUT: 3000,
APP_NAME: "MyApp"
});
// Попытка изменить константу
constants.MAX_CONNECTIONS = 200; // Не сработает
console.log(constants.MAX_CONNECTIONS); // 100
In this example, even if someone tries to change MAX_CONNECTIONS
the change will not occur and your application will remain stable.
OTUS experts talk more about programming languages in practical online courses. You can view the full catalog of courses via the link.