> Что происходит при попытке присвоить свойство примитиву в JavaScript (JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Яндекс

Стек: JavaScript

> Пример ответа

Короткий ответ

При попытке присвоить свойство примитиву JavaScript не выбрасывает ошибку, но и не сохраняет значение. В строгом режиме ("use strict") будет выброшена ошибка TypeError. Примитивы (кроме null и undefined) временно оборачиваются в объектные обёртки при доступе к свойствам, но эти обёртки сразу уничтожаются, поэтому присвоение теряется.

Подробное объяснение

В JavaScript примитивные типы (string, number, boolean, symbol, bigint) не являются объектами и не имеют собственных свойств. Однако при попытке обратиться к свойству примитива, движок создаёт временный объект-обёртку соответствующего типа (например, String, Number, Boolean). Это называется autoboxing.

При чтении свойства это работает прозрачно - вы получаете значение из прототипа обёртки. Но при присвоении происходит следующее:

  1. Создаётся временный объект-обёртка
  2. Свойство присваивается этому временному объекту
  3. Обёртка сразу уничтожается сборщиком мусора
  4. Исходный примитив остаётся неизменным

В нестрогом режиме операция выполняется молча, без ошибок. В строгом режиме ("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/undefined
let 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)
  • Путаница между чтением и записью свойств примитивов (чтение работает, запись - нет)
  • Игнорирование разницы между режимами выполнения
  • Предположение, что примитивы можно мутировать через их обёртки
  • Непонимание, что временная обёртка создаётся каждый раз заново

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью