Чтобы объяснить это, во-первых давайте вспомним, как функции конструктора работают в JavaScript:
function Guide(a) {
this.a = a;
}
Guide.prototype.q = "Life, the Universe, and Everything";
var g = new Guide(42);
console.log(g.q); // "Life, the Universe, and Everything"
console.log(g.a); // 42
Когда мы делаем new Guide(42)
, оператор new
создает новый объект и присваивает ему прототип используя Guide.prototype
свойства. Затем new
вызывает Guide
, передавая в этом новом объекте this
. Guide
использует this
для добавления свойств к новому объекту, который не является его прототипом. Затем выражение new
завершается, и его результатом является новый объект, который он создал.
Когда мы смотрим на g.q
, так как g
объект не имеет его собственный свойство называется q
, двигатель JavaScript смотрит на g
«s прототип, который (опять же) он получил назначен, когда она была создана. Этот прототип имеет свойство q
, поэтому двигатель использует его значение.
Напротив, когда мы смотрим на g.a
, объект g
имеет свое собственное имущество под названием a
, поэтому значение используется напрямую.
С этим фундаментом на месте, давайте посмотрим на Student
и Parent
:
function Student() {
// Call the parent constructor
Person.call(this);// <---- Confusion
}
Когда мы называем new Student()
, внутри вызова Student
, this
есть (опять же) новый объект, созданный new
оператора, имеет Student.prototype
в качестве базового прототипа. Но функция Parent
не имела возможности что-либо сделать с этим новым объектом. Итак, что делает эта строка, дает Parent
шанс сделать то, что ему нужно, сделать для новых объектов, которые он не может сделать с помощью прототипа, например, наша Guide
функция, назначая this.a
. С технической точки зрения, Parent.call(this);
вызывает функцию Parent
, гарантируя, что this
в вызове Parent
это значение, переданное в call
(который, в этом случае, this
вызова к Student
— например, новый объект). Если вы знакомы с языками на основе классов, это похоже на выполнение super();
(это Java, но вы получаете идею) в производном конструкторе: он дает базовому конструктору возможность инициализировать объект.
// inherit Person
Student.prototype = new Person(); //<---- Confusion
Поскольку Student
предполагается наследовать от Person
, то, что код делает это создание прототипа, который будет назначен для объектов, созданных с помощью new Student
. Объектом, который он создает, является объект Person
.
FWIW, что код не вполне реализует строительную цепь правильно (это чаще, чем это необходимо вызывая Person
[как при создании Student.prototype
и когда Student
называется], и не в состоянии установить constructor
).
Более правильный способ создать Student
«S prototype
свойства, если мы будем называть Parent
изнутри Student
, выглядит следующим образом:
function derive(child, parent) {
function ctor() { this.constructor = child; }
ctor.prototype = parent.prototype;
child.prototype = new ctor();
}
derive(Student, Parent);
Таким образом, мы получим прототип на основе Parent.prototype
, но без звонка Parent
. Это либо-либо: Либо вызов Parent
создать Student.prototype
, или вызов Parent
в Student
, но не то и другое. При построении иерархии с помощью функций-конструкторов обычно требуется вызвать родителя из дочернего конструктора, а не при создании дочернего прототипа. При использовании прямого наследования объектов (без функций конструктора), конечно, вы делаете это по-другому.
Если вы заинтересованы в наследование в JavaScript, я написал вспомогательный скрипт Lineage
вы можете захотеть взглянуть на, и, в частности, даже если вы не используете Lineage
, this discussion на своей странице вики может быть полезным для понимания иерархий наследования.
Я могу показаться очень глупым для людей, которые являются экспертами в javascript. Но будет очень рад, если вы прокомментируете и проголосуете. –
это разные вещи, которые вы должны больше узнать о вызове и применять методы javascript, это будет очень полезно, если вы хотите изучить этот язык программирования – Max
Я тоже не вижу причины для этого. Прототипное наследование сложно понять, и есть много неясной и откровенной неверной информации. –