Зарегистрируйтесь для доступа к 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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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