Ситуация: мы пишем программу для решения школьных геометрических задач. Чтобы потренироваться в написании классического кода на JavaScript, включаем строгий режим и пишем функции, каждая из которых будет решать свой класс задач. После пары тестовых задач становится ясно, что ответ не совпадает с тем, что в учебнике, — всё из-за того, что в школьных задачах число Пи равно 3,14, а JS использует более точное (и длинное) значение. Чтобы это исправить, мы пишем так:
Math.PI = 3.14;
Но при первом следующем запуске браузер останавливает выполнение кода с ошибкой:
❌ TypeError: Cannot assign to read only property 'PI' of object '#<Object>'
Непонятно, почему так? Всегда же работало, а тут — нет.
Что это значит: эта ошибка означает, что JavaScript не может поменять значение объекта, который используется только для чтения (read only).
Когда встречается: в любых ситуациях, когда мы пытаемся изменить что-то, предназначенное только для чтения, но не для записи. Такое бывает с константами, с «замороженными» объектами внутри функций, а также при использовании строгого режима — и вот это как раз наш случай.
Что делать с ошибкой TypeError: Cannot assign to read only property
Помните, при написании кода мы в самом начале включили строгий режим:
"use strict";
Особенность этого режима в том, что он позволяет писать более строгий, академический и безопасный код. Например, в строгом режиме нельзя:
- использовать переменные без их объявления;
- дублировать имена свойств в объектах;
- дублировать параметры функций;
- удалять переменные, функции и аргументы;
- использовать зарезервированные слова;
- использовать устаревшие конструкции.
Если бы строгий режим не был включён, мы бы спокойно поменяли значение числа Пи в JavaScript на любое другое, хоть на 300:
Но в строгом режиме готовые значения из встроенных констант языка менять нельзя. Если мы хотим использовать число Пи, равное 3,14, и при этом сохранить строгий режим, лучше сделать отдельную переменную и использовать её:
var pi;
pi = 3.14;
Точно так же и с другими служебными объектами. Например, в строгом режиме мы не можем поменять значение undefined на другое, а в обычном — можем:
"use strict";
undefined = 10;
Но без строгого режима — всё работает: