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

Что будет, если вызвать Proto у String?

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

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

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

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

Краткий ответ

Если вызвать String.prototype у примитива строки (например, "test".prototype), результатом будет undefined. Это происходит потому, что примитивы не имеют собственных свойств prototype. Однако, если обратиться к String.__proto__ или Object.getPrototypeOf(string), мы получим ссылку на прототип объекта-обёртки String.

Подробное объяснение

Чтобы понять это поведение, нужно разобраться в нескольких ключевых аспектах JavaScript: примитивы vs объекты, прототипы, объекты-обёртки и механизм прототипного наследования.

1. Примитивы не имеют свойства prototype

В JavaScript строки являются примитивными значениями, а не объектами. Свойство prototype существует только у функций-конструкторов (таких как String, Number, Array) и служит для наследования методов экземплярами. У самих экземпляров (включая объекты) свойства prototype нет.

console.log("test".prototype); // undefined
console.log(typeof "test"); // "string" (примитив)

2. Автоматическая упаковка в объект-обёртку

Когда мы пытаемся обратиться к свойству или методу у примитива (например, "test".length или "test".toUpperCase()), JavaScript временно упаковывает примитив в объект-обёртку (new String("test")). Этот объект имеет доступ к методам из String.prototype. После выполнения операции объект-обёртка уничтожается.

// Пример упаковки
const str = "hello";
console.log(str.toUpperCase()); // "HELLO"
// Происходит за кулисами: 
// 1. Создаётся временный объект: new String(str)
// 2. Вызывается метод toUpperCase()
// 3. Временный объект удаляется

3. Разница между __proto__, prototype и Object.getPrototypeOf()

  • prototype — свойство функции-конструктора, указывающее на объект, который будет использоваться как прототип для всех созданных экземпляров.
  • __proto__ (устаревшее, но поддерживаемое) — свойство экземпляра, ссылающееся на прототип его конструктора.
  • Object.getPrototypeOf() — современный способ получить прототип объекта.
// Для функции-конструктора String
console.log(String.prototype); // String {"", constructor: ƒ, ...}
console.log(String.prototype === Object.getPrototypeOf("")); // false (!)
// Потому что "" — примитив, а не объект

// Для объекта-обёртки
const strObj = new String("test");
console.log(Object.getPrototypeOf(strObj) === String.prototype); // true
console.log(strObj.__proto__ === String.prototype); // true (устаревший способ)

4. Что происходит при вызове Proto?

Если под Proto подразумевается обращение к prototype:

"строка".prototype; // undefined

Если под Proto подразумевается обращение к __proto__:

"строка".__proto__; // String {"", constructor: ƒ, ...}
// Здесь работает упаковка в объект-обёртку,
// и __proto__ ссылается на String.prototype

5. Практический пример и важные выводы

// 1. prototype есть только у функций
function MyFunc() {}
console.log(MyFunc.prototype); // {constructor: ƒ}

// 2. У примитивов нет prototype
console.log((123).prototype); // undefined
console.log(true.prototype); // undefined

// 3. Но у них есть доступ к методам через прототип конструктора
console.log("test".toUpperCase()); // "TEST" - из String.prototype
console.log("test".__proto__.toUpperCase); // ƒ toUpperCase()

// 4. Цепочка прототипов для строки:
const str = "example";
// str (примитив) → временный String объект → String.prototype → Object.prototype → null
console.log(Object.getPrototypeOf(String.prototype) === Object.prototype); // true

Ключевые моменты:

  • prototype существует только у функций-конструкторов
  • Примитивы (строки, числа, булевы) не имеют собственных свойств
  • Автоматическая упаковка позволяет примитивам использовать методы объектов
  • String.prototype содержит все стандартные методы для работы со строками
  • Для проверки прототипа используйте Object.getPrototypeOf() вместо __proto__

Понимание этой механики критически важно для работы с наследованием, оптимизацией (чтобы избежать неявного создания объектов-обёрток в циклах) и для отладки сложных сценариев в JavaScript.