Ответ
В JavaScript примитивные типы (кроме null и undefined) могут иметь методы благодаря механизму обёрток (wrapper objects). Когда вызывается метод у примитива, JS автоматически создаёт временный объект-обёртку (String, Number, Boolean), вызывает метод, а затем удаляет обёртку.
const str = 'hello';
console.log(str.toUpperCase()); // "HELLO"
// Эквивалентно:
// const temp = new String(str);
// temp.toUpperCase();
// temp = null;
Это позволяет работать с примитивами как с объектами, но без постоянного хранения в памяти.