Небольшое дополнение

В продолжении статьи про const хочется добавить еще примеры использования слова const для создания полной иммутабельности. В принципе иммутабельность можно рассматривать как альтернативу строгой типизации для того, чтобы максимально защитить код. Я за свои 15+ лет видел много кода где переменная терялась или преопределялась повторно или меняла свое значение. И все это были случайные ошибки.

Мы можем использовать const в циклах, если хотим быть уверены что полученное значение из итерируемого объекта будет неизменяемым. Допустим у нас есть некоторый источник данных и мы работаем с каждым элементом в итерации:

for (const user of userList()) {
// совершаем сложные манипуляции, много строк кода
// вдруг случайно кто-то написал
    user = someWtfObject.getUserNameFromUserObj( user )
    // И вот в таком случае мы сохраним оригинальный объект
// и не позволим его переопределить,
// даже если кто-то очень захотел
    console.log( user )
}

Но вы можете возразить: ты же сам писал что мы только холдим ссылку на объект, а сам объект остается мутабельным. Как его защитить?

Кстати хороший вопрос, достойный собеседования. Как зафризить объект user в нашем цикле не внося правок в источник? Ведь мы же не можем написать так:

for (const user of userList()) {
user = Object.freeze(user);
}

Такой вариант выдаст исключение:

error TypeError: Assignment to constant variable.

Как быть? Логично что мы можем определить новый фриз объект, но оригинальный останется мутабельным. Вариант:

for (const user of userList()) {
const User = Object.freeze(user);
}

не подходит под условие нашего вопроса. Нам нужно сделать иммутабельным объект user в контексте цикла не прибегая к модификации источника данных и не создавая новых объектов.

В прошлой статье я забыл упомянуть, что Object.freeze умеет замораживать объекты по ссылке. Хоть он и возвращает замороженный объект, тем не менее, можно обойтись без присваивания. Он умеет работать с объектами по ссылке:

for (const user of userList()) {
  Object.freeze(user);
user.userId = 123; // value will not be changed
}

Теперь у нас неизменяемый объект-константа внутри итерации, который живет только внутри итерации и умрет как только итерация закончится (при условии что не останется живых ссылок на эту область видимости).

Про работу c ссылками и про вопросы на собеседованиях по этой теме я расскажу в следующих статьях.

Вопрос головломка

Что будет?

for (const i=0;i<10;i++);

Задумались? Не буду писать ответ, так как сами сможете его получить, банально вставив код в DevTools. 🙂