> Что происходит при попытке присвоить свойство примитиву в JavaScript (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Яндекс
Стек: JavaScript
> Пример ответа
Короткий ответ
При попытке присвоить свойство примитиву JavaScript не выбрасывает ошибку, но и не сохраняет значение. В строгом режиме ("use strict") будет выброшена ошибка TypeError. Примитивы (кроме null и undefined) временно оборачиваются в объектные обёртки при доступе к свойствам, но эти обёртки сразу уничтожаются, поэтому присвоение теряется.
Подробное объяснение
В JavaScript примитивные типы (string, number, boolean, symbol, bigint) не являются объектами и не имеют собственных свойств. Однако при попытке обратиться к свойству примитива, движок создаёт временный объект-обёртку соответствующего типа (например, String, Number, Boolean). Это называется autoboxing.
При чтении свойства это работает прозрачно - вы получаете значение из прототипа обёртки. Но при присвоении происходит следующее:
- Создаётся временный объект-обёртка
- Свойство присваивается этому временному объекту
- Обёртка сразу уничтожается сборщиком мусора
- Исходный примитив остаётся неизменным
В нестрогом режиме операция выполняется молча, без ошибок. В строгом режиме ("use strict") JavaScript выбрасывает TypeError, так как попытка изменить примитив считается недопустимой.
Исключение составляют null и undefined - при попытке присвоить им свойство всегда выбрасывается ошибка, даже в нестрогом режиме.
На практике
Эта особенность часто приводит к трудноуловимым багам, когда разработчик ожидает, что примитив ведёт себя как объект. Например, попытка кешировать результат вычисления на строке или числе не сработает.
При работе с примитивами важно помнить:
- Не пытайтесь добавлять свойства примитивам - они не сохранятся
- Для хранения дополнительных данных используйте объекты или Map
- Если нужно расширить поведение примитивов, используйте прототипы (например,
String.prototype), но делайте это осторожно, чтобы не нарушить ожидания других разработчиков
Пример кода
JAVASCRIPT// Нестрогий режимlet str = 'hello';str.customProp = 'world';console.log(str.customProp); // undefined - свойство потеряно// Строгий режим'use strict';let num = 42;num.value = 100; // TypeError: Cannot create property on primitive value// Исключение для null/undefinedlet empty = null;empty.prop = 'test'; // TypeError: Cannot set properties of null// Autoboxing при чтении работаетconsole.log('hello'.length); // 5 - временная обёртка String
Как отвечать на собеседовании
Начните с чёткого объяснения механизма autoboxing и временных обёрток. Подчеркните разницу между строгим и нестрогим режимом. Упомяните, что null и undefined ведут себя иначе. Приведите практический пример, показывающий, что присвоение не сохраняется. Если спросят про производительность, отметьте, что создание временных обёрток - быстрая операция, но злоупотребление может привести к лишней работе GC.
Что проверяет интервьюер
- Понимание разницы между примитивами и объектами в JavaScript
- Знание механизма autoboxing и временных обёрток
- Осведомлённость о различиях строгого и нестрогого режимов
- Понимание, почему
nullиundefinedне имеют обёрток - Способность объяснить практические последствия этой особенности
Типичные ошибки
- Утверждение, что присвоение свойства примитиву всегда выбрасывает ошибку (верно только для строгого режима и
null/undefined) - Путаница между чтением и записью свойств примитивов (чтение работает, запись - нет)
- Игнорирование разницы между режимами выполнения
- Предположение, что примитивы можно мутировать через их обёртки
- Непонимание, что временная обёртка создаётся каждый раз заново
> Похожие задачи по frontend
Что такое AbortController и метод abort в JavaScript
Как работает Promise.all и как реализовать аналог с обработкой reject в JavaScript
Что такое лексическое окружение в JavaScript и как оно работает
Что такое Redux, зачем он нужен и как устроен
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью