Чтобы добавить к ответу Норберта Хартла , SuperCar.prototype.constructor не нужен, но некоторые люди используют его как удобный способ получения функции построения объекта (в данном случае это объекты SuperCar) .
Только в первом примере Car.call (this, name) находится в функции конструктора SuperCar, потому что, когда вы делаете это:
var mySuperCar = new SuperCar("SuperCar");
Вот что делает JavaScript:
- Создается новый пустой объект.
- Для внутреннего прототипа нового объекта установлено значение Car.
- Функция конструктора SuperCar запускается.
- Готовый объект возвращается и устанавливается в mySuperCar.
Обратите внимание, что JavaScript не назвал Car для вас. Прототипы, какими бы они ни были, любые свойства или методы, которые вы не установили для SuperCar, будут найдены в Car. Иногда это хорошо, например У SuperCar нет метода Drive, но он может использовать метод Car, поэтому все SuperCar будут использовать один и тот же метод Drive. В других случаях вы не хотите делиться, например, каждый SuperCar имеет свое имя. Так как же настроить имя каждого SuperCar на свое? Вы можете установить this.Name внутри функции конструктора SuperCar:
function SuperCar(name){
this.Name = name;
}
Это работает, но подождите секунду. Разве мы не сделали то же самое в конструкторе Car? Не хочу повторяться. Так как Car уже задает имя, давайте просто назовем его.
function SuperCar(name){
this = Car(name);
}
Ой, вы никогда не захотите изменить специальную ссылку на объект this
. Помните 4 шага? Держитесь за тот объект, который дал вам JavaScript, потому что это единственный способ сохранить драгоценную внутреннюю связь прототипа между вашим объектом SuperCar и Car. Так как же нам установить Name, не повторяя себя и не выбрасывая наш новый объект SuperCar, JavaScript потратил столько особых усилий, чтобы подготовиться к нам?
Две вещи. Один: значение this
является гибким. Два: Автомобиль - это функция. Можно вызывать Car не с нетронутым, свежим экземпляром объекта, а вместо этого, скажем, с объектом SuperCar. Это дает нам окончательное решение, которое является частью первого примера в вашем вопросе:
function SuperCar(name){
Car.call(this, name);
}
Как функция, Car может быть вызван с помощью метода вызова функции , который изменяет значение this
в Car на экземпляр SuperCar, который мы создаем. Presto! Теперь каждый SuperCar получает свое собственное свойство Name.
В заключение, Car.call(this, name)
в конструкторе SuperCar дает каждому новому объекту SuperCar свое уникальное свойство Name, но без дублирования кода, который уже находится в Car.
Прототипы не страшны, когда вы их понимаете, но они совсем не похожи на классическую модель ООП класса / наследования. Я написал статью о концепции прототипов в JavaScript . Он написан для игрового движка, использующего JavaScript, но это тот же движок JavaScript, что и Firefox, поэтому он должен быть актуальным. Надеюсь, это поможет.