---
sidebar_position: 3
---

# Встроенные прототипы

- Все встроенные объекты следуют одному шаблону:
  - Методы хранятся в прототипах (Array.prototype, Object.prototype, Date.prototype и т.д.).
  - Сами объекты хранят только данные (элементы массивов, свойства объектов, даты).
- Примитивы также хранят свои методы в прототипах объектов-обёрток: Number.prototype, String.prototype, Boolean.prototype. Только у значений undefined и null нет объектов-обёрток.
- Встроенные прототипы могут быть изменены или дополнены новыми методами. Но не рекомендуется менять их. Единственная допустимая причина – это добавление нового метода из стандарта, который ещё не поддерживается движком JavaScript.


## Object.prototype
Краткая нотация `obj = {}` – это то же самое, что и `obj = new Object()`, где `Object` – встроенная функция-конструктор для объектов с собственным свойством `prototype`, которое ссылается на огромный объект с методом `toString` и другими.
```js
let obj = {};
alert( obj ); // "[object Object]" ?
```
Таким образом, когда вызывается obj.toString(), метод берётся из Object.prototype.

## Другие встроенные прототипы
Другие встроенные объекты, такие как Array, Date, Function и другие, также хранят свои методы в прототипах.

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

Если мы попытаемся получить доступ к их свойствам, то тогда будет создан временный объект-обёртка с использованием встроенных конструкторов String, Number и Boolean, который предоставит методы и после этого исчезнет.
Эти объекты создаются невидимо для нас, и большая часть движков оптимизирует этот процесс, но спецификация описывает это именно таким образом. Методы этих объектов также находятся в прототипах, доступных как String.prototype, Number.prototype и Boolean.prototype.

💥 **Значения null и undefined не имеют объектов-обёрток**

## Изменение встроенных прототипов
Встроенные прототипы можно изменять. Например, если добавить метод к String.prototype, метод становится доступен для всех строк:
```js
String.prototype.show = function() {
  alert(this);
};
"BOOM!".show(); // BOOM!
```
💥 Важно:
Прототипы глобальны, поэтому очень легко могут возникнуть конфликты. Если две библиотеки добавляют метод String.prototype.show, то одна из них перепишет метод другой.

Изменение встроенных прототипов считается плохой идеей.
*** В современном программировании есть только один случай, в котором одобряется изменение встроенных прототипов. Это создание полифилов.***

## Заимствование у прототипов
Некоторые методы встроенных прототипов часто одалживают.

Например, если мы создаём объект, похожий на массив (псевдомассив), мы можем скопировать некоторые методы из Array в этот объект.
```js
let obj = {
  0: "Hello",
  1: "world!",
  length: 2,
};
obj.join = Array.prototype.join;
alert( obj.join(',') ); // Hello,world!
```
Это работает, потому что для внутреннего алгоритма встроенного метода `join` важны только корректность индексов и свойство `length`, он не проверяет, является ли объект на самом деле массивом. И многие встроенные методы работают так же.

Альтернативная возможность – мы можем унаследовать от массива, установив `obj.__proto__` как `Array.prototype`, таким образом все методы `Array` станут автоматически доступны в `obj`.

Но это будет невозможно, если `obj` уже наследует от другого объекта. Помните, мы можем наследовать только от одного объекта одновременно.

Заимствование методов – гибкий способ, позволяющий смешивать функциональность разных объектов по необходимости.

🚀 **Источник: [https://learn.javascript.ru/native-prototypes](https://learn.javascript.ru/native-prototypes)**