Прежде всего, прототип - это просто объект. Почти каждый объект в JS (за исключением, например, когда вы используете Object.create(null)
) имеет некоторый прототип, и прототипы могут быть объединены в цепочку.
Пример: когда вы создаете массив с использованием литерала []
, ваш экземпляр массивасвязан с объектом (также экземпляром массива), определяющим свойства массива, такими как map
и т. д., который сам связан с другим прототипом (экземпляром объекта), определяющим свойства объектов, таких как toString
. Эти свойства обычно являются функциями. Теперь, когда вы получаете доступ к одному из свойств вашего объекта, например [].hasOwnProperty
, движок ищет цепочку прототипов, чтобы найти его. Он начинается в вашем экземпляре []
, не находит его, продолжается до прототипа (массива), также безуспешно, поэтому переходит к последнему прототипу (экземпляру объекта), где он, наконец, найден.
Как видите, цепочка прототипов всегда где-то заканчивается, поэтому, если вы попытаетесь получить прототип на последнем прототипе в цепочке, вы получите null
.
Теперь вернемся к конструктору. функции. Первое, что нужно отметить, это то, что это просто обычные функции - фактическим «создателем» экземпляра является ключевое слово new
. Теперь каждая функция имеет свойство prototype
, которое говорит вам следующее: каждый объект, созданный с помощью этой функции, будет связан с прототипом со всем, что находится в свойстве prototype
функции. По умолчанию каждая функция содержит экземпляр Object в этом свойстве, что означает, что каждый объект, который вы создаете из этой функции, будет связан с этим экземпляром с помощью прототипа и, следовательно, будет «наследовать» такие свойства, как toString
.
Вы можете увидеть связь между свойством prototype
функции и прототипом экземпляра в этом примере.
function A() {}
var a = new A();
a.__proto__ == A.prototype; // is true
И последнее, свойство constructor
в свойстве prototype
функции говорит вам,какая функция будет использоваться для создания новых экземпляров при использовании функции с ключевым словом new
. Этот глоток сводится к:
function A() {}
A == A.prototype.constructor; // is true
Это ссылка на себя. Это свойство было необязательным для установки при создании собственной цепочки наследования до ES6, но, тем не менее, было сделано для правильности.
Так что же такое прототип? Это просто объект, связанный с другими экземплярами объекта через специальное соединение с прототипом, предоставляя ему доступ к предопределенным свойствам. Это способ сделать наследование в JS.