← Назад к вопросам

У примитивов отсутствует __proto__ или prototype

1.0 Junior🔥 121 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

У примитивов отсутствует proto или prototype

Это высказывание частично истинно, но неточно. Давайте разберёмся в деталях, так как это очень тонкий момент в JavaScript.

Что такое примитивы?

Примитивные типы в JavaScript:

  • number
  • string
  • boolean
  • undefined
  • null
  • symbol
  • bigint

Это встроенные типы данных, в отличие от объектов.

Ошибка в высказывании

Примитивы ИМЕЮТ proto! Вот доказательство:

const str = 'hello';
const num = 42;
const bool = true;

console.log(str.__proto__); // String.prototype {...}
console.log(num.__proto__); // Number.prototype {0: 0, ...}
console.log(bool.__proto__); // Boolean.prototype {}

// Примитивы имеют методы благодаря __proto__!
console.log(str.toUpperCase()); // "HELLO" — это работает!
console.log(num.toFixed(2)); // "42.00" — это работает!
console.log(bool.toString()); // "true" — это работает!

Как это работает? Автоматическое обёртывание (Boxing)

Когда вы вызываете метод на примитиве, JavaScript автоматически обёртывает его в объект:

const str = 'hello';

// Эта строка...
str.toUpperCase();

// Внутренне преобразуется в...
new String(str).toUpperCase();
// Вызывается метод
// Объект удаляется (garbage collection)

Это происходит за кулисами — вы не видите создание объекта.

Что такое proto и prototype?

proto — это внутренний объект, который указывает на прототип объекта.

const str = 'hello';

// __proto__ указывает на String.prototype
console.log(str.__proto__ === String.prototype); // true

// Через __proto__ мы можем получить доступ к методам String.prototype
console.log(str.__proto__.toUpperCase); // [Function: toUpperCase]

prototype — это свойство, которое есть только у функций конструкторов, не у примитивов:

function MyConstructor() {}

// У функции есть prototype
console.log(MyConstructor.prototype); // { constructor: MyConstructor }

// У примитива нет prototype
const str = 'hello';
console.log(str.prototype); // undefined

Таблица истины

protoprototype
Примитивы (string, number)✅ ИМЕЮТ (автоматическое обёртывание)❌ НЕ имеют
Объекты✅ ИМЕЮТ❌ НЕ имеют (если не функции)
Функции конструкторы✅ ИМЕЮТ✅ ИМЕЮТ

Демонстрация с примитивами

// 1. Строка
const myString = 'JavaScript';
console.log(myString.__proto__); // String.prototype
console.log(myString.prototype); // undefined

// 2. Число
const myNumber = 123;
console.log(myNumber.__proto__); // Number.prototype
console.log(myNumber.prototype); // undefined

// 3. Boolean
const myBool = false;
console.log(myBool.__proto__); // Boolean.prototype
console.log(myBool.prototype); // undefined

Цепочка прототипов для примитивов

const str = 'hello';

// Цепочка: str.__proto__ → String.prototype → Object.prototype → null
console.log(str.__proto__); // String.prototype
console.log(str.__proto__.__proto__); // Object.prototype
console.log(str.__proto__.__proto__.__proto__); // null

Практический пример

// Вы можете добавлять методы к примитивам через их прототип
String.prototype.reverse = function() {
  return this.split('').reverse().join('');
};

const str = 'hello';
console.log(str.reverse()); // "olleh"

// ВАЖНО: не рекомендуется изменять встроенные прототипы!
// Это может привести к конфликтам и ошибкам

Почему примитивы имеют методы?

Без механизма обёртывания, примитивы не могут иметь методы. JavaScript решил эту проблему через автоматическое обёртывание (autoboxing):

const num = 42;
num.toString(); // "42"

// Внутренне:
// const temp = new Number(num);
// const result = temp.toString();
// (temp удаляется)

Что такое null и undefined?

Они — исключение из правила:

const nothing = null;
const undef = undefined;

console.log(nothing.__proto__); // Ошибка: Cannot read property '__proto__' of null
console.log(undef.__proto__); // Ошибка: Cannot read property '__proto__' of undefined

Проверка типа через прототип

const str = 'hello';

// Проверяем через instanceof (не работает на примитивах напрямую)
console.log(str instanceof String); // false

const strObj = new String('hello');
console.log(strObj instanceof String); // true

// Правильная проверка типа примитива
console.log(typeof str); // "string"
console.log(typeof strObj); // "object"

Корректный ответ на вопрос

Высказывание неточно:

  1. proto: Примитивы ИМЕЮТ proto, который указывает на их конструктор (String.prototype, Number.prototype и т.д.). Это возможно благодаря автоматическому обёртыванию.

  2. prototype: Примитивы НЕ имеют своего prototype (это есть только у функций).

Правильное утверждение: Примитивы не имеют собственного prototype, но имеют proto, который указывает на прототип их встроенного конструктора (String.prototype, Number.prototype и т.д.).

Визуализация

Примитив: "hello"
    ↓
    __proto__ → String.prototype
                ↓
                __proto__ → Object.prototype
                            ↓
                            __proto__ → null

        prototype: undefined (у примитива его нет)

Это различие важно для понимания, как JavaScript обрабатывает методы на примитивах и как устроена цепочка наследования.