Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Упаковка и Распаковка (Boxing) JS: Введение в ООП

Методы – это свойства объектов, в которые записаны функции. Если это так, тогда почему работает такой код:

'hexlet'.toUpperCase(); // "HEXLET"

Из этого кода можно сделать ошибочный вывод что строка это тоже объект, но это не так. В JavaScript строки, логические значения, null и числа реализованы как примитивные значения, у них нет методов. С другой стороны, для каждого такого типа существует собственный конструктор, "упаковывающий" примитивный тип в объект:

typeof 'hexlet'; // "string"
const name = new String('hexlet');
typeof name; // "object"
console.log(name); // "hexlet"

JavaScript автоматически упаковывает примитивные типы в соответствующие объекты, когда встречает вызовы методов на них (и затем автоматически распаковывает). То есть в действительности, все методы которые мы вызываем на строках, хранятся в прототипе конструктора String. То же самое касается и всех остальных типов:

// Ручная упаковка примитивных значений
const number = new Number(1);
number.toString(); // "1"
const bool = new Boolean(true);
bool.toString(); // "true"

// Автоматическая упаковка
const one = 1;
// Во время вызова происходит упаковка
one.toString(); // "1"
// Обратите внимание что, такой код завершится с ошибкой:
// 1.toString();
// js ожидает, что после точки будет продолжение числа
// А вот так заработает (1).toString();

const yes = true;
// Во время вызова происходит упаковка
yes.toString(); // "true"

Интересно то, как происходит распаковка. Для этого JavaScript автоматически вызывает метод valueOf() у объекта:

const number = new Number(100);
// Его можно вызвать самостоятельно
number.valueOf(); // 100

// А еще он вызывается в результате разных операций над объектом
const newName = `${number} is a big number`; // "100 is a big number!"

В отличие от упаковки, распаковка выполняется абсолютно для всех объектов. Это позволяет определять valueOf() самостоятельно:

const words = ['Hello'];
const helloBuilder = (string) => words.push(string);
const build = () => words.join(' ');

helloBuilder.valueOf = () => build();

helloBuilder('from');
helloBuilder('valueOf');

console.log(helloBuilder == 'Hello from valueOf'); // true

Подобным пользуются разные библиотеки, например moment.js для конвертации даты (как объекта) в значение (timestamp):

const date = moment(); // возвращает объект описывающий текущую дату
// с этой датой можно делать всякое
date.startOf('day').fromNow(); // "a day ago"

// Хитрость в том, что оператор `+` приводит к распаковке
// valueOf возвращает текущий timestamp
+date; // 1578624487377

Хотя это работает, такой подход не приветствуется многими разработчиками. Это больше похоже на хак, чем на хороший код.


Дополнительные материалы

  1. Документация по valueOf на MDN
  2. Boxing Wrappers

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.

Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Фронтенд-разработчик
Профессия
Разработка фронтенд-компонентов веб-приложений
1 июня 10 месяцев
Иконка программы Node.js-разработчик
Профессия
Разработка бэкенд-компонентов веб-приложений
1 июня 10 месяцев
Иконка программы Fullstack-разработчик
Профессия
Новый
Разработка фронтенд и бэкенд компонентов веб-приложений
1 июня 16 месяцев

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»