#javascript #function #constructor #prototype
#javascript #функция #конструктор #прототип
Вопрос:
Я просматривал объяснение Mozilla о наследовании прототипов https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain . Думал попробовать какой-нибудь пример в консоли Chrome.
function f() {
this.a =1;
this.b =2;
}
let o = new f();
f.prototype.b =3;
f.prototype.c =4;
Я заметил, что прототип функции f() имеет конструктор, и у него снова есть прототип, и он продолжает работать, как показано ниже:
f.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor
Теперь, согласно документации Mozilla, «Каждый объект имеет частное свойство, которое содержит ссылку на другой объект, называемый его прототипом. У этого объекта-прототипа есть свой собственный прототип, и так далее, пока не будет достигнут объект с null в качестве прототипа. По определению, null не имеет прототипа и действует как последнее звено в этой цепочке прототипов »
Я уверен, что смотрю на это под неправильным углом. Может кто-нибудь изложить здесь некоторую перспективу. Что на самом деле происходит? почему у нас бесконечная цепочка конструкторов и прототипов?
Комментарии:
1. Объекты Javascript имеют прототип, который, в свою очередь, представлен объектами Javascript.
Ответ №1:
У вас есть циклическая ссылка. Учитывая функцию, вы можете получить доступ к prototype
ее свойству, чтобы получить доступ к объекту, который будет внутренним прототипом любых экземпляров.
function f() {
this.a =1;
this.b =2;
}
let o = new f();
console.log(f.prototype === Object.getPrototypeOf(o));
Для этого .prototype
объекта вы можете получить доступ к его constructor
свойству, чтобы вернуться к связанной функции.
Функции .prototype
и .constructor
этого прототипа являются ссылками друг на друга. Учитывая любой из них, вы можете получить доступ к другому.
Фактическая цепочка прототипов для f
:
f <- Function.prototype <- Object.prototype
Цепочка прототипов для o
:
o <- f.prototype <- Object.prototype
Обратите внимание, что .prototype
свойство не ссылается на объект, который является внутренним прототипом того, на который вы его вызываете. Чтобы добраться до внутреннего прототипа некоторого объекта obj
, вы должны использовать Object.getPrototypeOf
(или __proto__
, который устарел). .prototype
Свойство — это специальное свойство функций, которое будет ссылаться на внутренний прототип любых экземпляров этой функции, которые могут быть созданы. Например const instance = new SomeClass()
, это приведет к instance
созданию внутреннего прототипа SomeClass.prototype
.
Комментарии:
1. Спасибо @CertainPerformance Не могли бы вы предоставить более подробную информацию о внутренней функциональности прототипа? Служит ли эта циклическая ссылка какой-либо цели? Почему Javascript имеет это в первую очередь?
2. Внутренняя цепочка прототипов — это то, о чем вы можете (и, возможно, читали) во многих руководствах — у каждого объекта есть внутренний прототип какого-либо другого объекта или
null
, как правило, вершина цепочки прототиповObject.prototype
, хотя можно создать что-то, что не наследуется сObject.prototype
помощьюObject.create
.3. Циклическая ссылка предназначена только для удобства — если все, что у вас есть, это функция, вы можете перейти к внутреннему прототипу. Но если все, что у вас есть, это внутренний прототип, вы можете перейти к функции.
4. Еще раз спасибо @CertainPerformance. Итак
console.log(f.prototype === Object.getPrototypeOf(o));
, истинная причина, по которой каждый объект наследует от Object. Я прав?5. Также не могли бы вы также объяснить, почему
f.prototype === Object.getPrototypeOf(f)
результаты являются ложными?