Зарегистрируйтесь, чтобы продолжить обучение

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

Любой метод — это функция в свойстве объекта. Когда мы вызываем метод, то вызываем функцию из свойства:

const obj = {
  sayHello: () => console.log('hello!'),
}

obj.sayHello()

Однако JavaScript позволяет вызывать функции не только на объектах, но и на примитивных значениях:

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

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

Во время вызова методов на примитивных значениях JavaScript автоматически упаковывает значение в объект и вызывает метод на этом объекте. После этого объект автоматически распаковывается на примитивное значение.

Для каждого примитивного типа в JavaScript есть конструктор, который создает объект из примитивного значения. Именно он и вызывается, когда происходит упаковка.

Чтобы разобраться в этой теме, выполним ручную упаковку на примере выше. Конструктором для строк является String:

const name = new String('hexlet')
console.log(`${name}`) // "hexlet"

Здесь мы создали объект name и упаковали в него примитивное значение — строку 'hexlet'.

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

const name = new String('hexlet')
// Его можно вызвать самостоятельно
name.valueOf() // "hexlet"

То же самое касается других типов:

const number = new Number(100)
number.valueOf() // 100

const bool = new Boolean(true)
bool.valueOf() // true

Метод valueOf() вызывается в результате разных операций над объектом:

const number = new Number(100)

const newName = `${number + 0} is a big number` // "100 is a big number!"

В примере выше мы вычислили значение number и соединили его в строку. Чтобы это сделать, мы сложили number + 0. Благодаря этому JavaScript автоматически вызвал метод valueOf() на объекте number, чтобы вычислить его значение для операции сложения.

Мы можем переопределить метод valueOf():

const number = new Number(100)
number.valueOf = () => 99999

const newName = `${number + 0} is a big number` // "99999 is a big number!"

Итог

Когда мы вызываем методы на примитивных значениях, JavaScript автоматически упаковывает эти значения в объекты, вызывает методы и распаковывает значения обратно. Распаковка происходит не только на примитивных значениях, но и обычных объектах, когда они участвуют в вычислениях.

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


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

  1. Документация по valueOf на MDN
  2. Обертки

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

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

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

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

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

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

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

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff