Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Константы в JavaScript: изменяемость и ограничения
Ключевое слово const в JavaScript создаёт константную ссылку на значение, а не делает неизменным само значение. Это фундаментальное различие, которое часто вызывает путаницу.
Что НЕЛЬЗЯ изменить в const?
-
Нельзя переназначить переменную:
const PI = 3.14159; PI = 3.14; // Ошибка: Assignment to constant variable. const user = { name: "Alice" }; user = { name: "Bob" }; // Ошибка! Менять ссылку запрещено. -
Нельзя повторно объявить переменную в той же области видимости:
const x = 10; const x = 20; // Ошибка: Identifier 'x' has already been declared
Что МОЖНО изменить в const?
Если значением const является мутабельный (изменяемый) объект — объект, массив, функция, Map, Set и т.д. — вы можете изменять внутреннее содержимое этого объекта. Ссылка на сам объект остаётся неизменной.
1. Изменение свойств объекта
const person = {
name: "John",
age: 30
};
person.age = 31; // Можно! Изменяем свойство
person.city = "London"; // Можно! Добавляем новое свойство
delete person.name; // Можно! Удаляем свойство
console.log(person); // { age: 31, city: "London" }
2. Изменение элементов массива
const numbers = [1, 2, 3];
numbers[0] = 100; // Можно! Меняем элемент
numbers.push(4); // Можно! Добавляем элемент
numbers.pop(); // Можно! Удаляем элемент
numbers.splice(1, 1); // Можно! Удаляем элемент по индексу
console.log(numbers); // [100, 3]
3. Изменение содержимого коллекций ES6
const map = new Map([['key1', 'value1']]);
map.set('key2', 'value2'); // Можно!
map.delete('key1'); // Можно!
const set = new Set([1, 2, 3]);
set.add(4); // Можно!
set.delete(1); // Можно!
Как сделать объекты по-настоящему неизменяемыми?
Если вам нужно защитить содержимое объекта от изменений, используйте следующие методы:
Object.freeze() — поверхностная заморозка
const config = Object.freeze({
apiUrl: 'https://api.example.com',
timeout: 5000
});
config.timeout = 10000; // Не сработает в strict mode
config.newProp = true; // Не сработает
console.log(config); // { apiUrl: 'https://api.example.com', timeout: 5000 }
// Но! freeze() неглубокий:
const nestedObj = Object.freeze({ data: { x: 1 } });
nestedObj.data.x = 2; // Сработает! Вложенные объекты можно менять
Глубокая заморозка (рекурсивная)
Для полной защиты нужно реализовать глубокую заморозку:
function deepFreeze(obj) {
Object.freeze(obj);
Object.keys(obj).forEach(key => {
if (typeof obj[key] === 'object' && obj[key] !== null) {
deepFreeze(obj[key]);
}
});
return obj;
}
Практические рекомендации и паттерны
-
Используйте
constпо умолчанию для всех объявлений переменных. Переходите кletтолько когда действительно нужно переназначение. -
Именование констант: для примитивных значений, которые не должны меняться, используйте UPPER_CASE:
const MAX_USERS = 100; const API_ENDPOINT = 'https://api.example.com/data'; -
Для иммутабельных обновлений объектов и массивов создавайте новые экземпляры:
const originalArray = [1, 2, 3]; const newArray = [...originalArray, 4]; // Создаём новый массив const originalObj = { a: 1, b: 2 }; const updatedObj = { ...originalObj, c: 3 }; // Создаём новый объект
Выводы
constгарантирует неизменность ссылки, а не значения.- Примитивные значения (строки, числа, булевы) в
constдействительно неизменны, так как они не являются объектами. - Объекты, массивы и другие мутабельные структуры могут изменяться по содержимому даже при объявлении через
const. - Для реальной защиты данных используйте
Object.freeze()или библиотеки иммутабельности (Immutable.js, Immer).
Использование const — это в первую очередь сигнал о намерениях разработчика: "эта ссылка не должна переназначаться". Это улучшает читаемость кода и предотвращает случайные переприсваивания, но не заменяет продуманную архитектуру данных с контролируемыми мутациями.