Прямо сейчас идет день открытых дверей по курсу «Разработчик на Spring Framework». Присоединяйтесь!

Откуда методы у типов number, string и boolean в JS?

JS_Deep_10-5020-ba80b4.10_site.png

Прочитав эту заметку, вы никогда не захотите писать на 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, то всё должно быть понятно — попробуйте! Пишите ответы и вопросы в комментариях!

Автор
1 комментарий
0

Получается ответ undefined. Так как, когда интерпретатор видит обращение к свойству или методу примитива, он создает для него объект-обертку. В данном случае он свойству hello присваивается строка hello. Но также мы знаем что после того как присваивание или если бы это было вызов объект-обертка будет удалена.

Поэтому в console.log ничего не выведет, так как объект-обертка удалена к моменту его выполнения.

А именно undefined ответ, так как обращение к несуществующему свойству объекта возвращает undefined. Опять таки получается в console.log идет обращение у примитива к свойству, то есть он опять создает объект-обертку. Но у него нет свойства hello, вот поэтому ответ undefined! А нет свойства так как выше он был сразу удален :). Ух, ну и задачка, надеюсь я все правильно понял.

Для комментирования необходимо авторизоваться