Откуда методы у типов number, string и boolean в JS?
Прочитав эту заметку, вы никогда не захотите писать на JavaScript. Но подождите! В работе эти проблемы не всплывают почти никогда. Я специально для вас залезу в этот тёмный подвал JS, чтобы поведать о том, как работает (255).toString(16) и ('me: hello').substr(4) и откуда у примитивных типов number, string и boolean методы?
Элегантный трюк JS
Как мы знаем, эти типы примитивные, то есть их значения — не объекты. Каждому «интересному» примитивному типу соответствует класс: Number, String и Boolean. Методы (toString, toLowerCase, substr) определены у этих типов-обёрток.
И каждый раз когда мы пытаемся получить свойство (или метод) примитивного значения, оно автоматически оборачивается в соответствующий объект, так что ('x').toLowerCase() превращается в (new String('x')).toLowerCase().
Такое оборачивание называется Boxing — положить в коробочку. После выполнения метода объект-обёртка просто выбрасывается.
Объекты типа Number — настоящие объекты, со всеми вытекающими бонусами и проблемами: new Number(3) !== new Number(3), потому что теперь значения сравниваются по ссылке.
Никогда не используйте типы-обёртки с new как конструктор. Скорее всего, вы хотите именно значение примитивного типа: Number('3') === 3.
Попрактикуемся?
На собеседованиях мне несколько раз давали хитрую (но бесполезную) задачку. Что произойдет в результате выполнения этого кода:
const x = 10; x.hello = 'hello'; console.log(x.hello);
Если вы знаете про Boxing, то всё должно быть понятно — попробуйте! Пишите ответы и вопросы в комментариях!