Рассмотрим одно из этих определений
Рисунок 8.6 Специфицирование свойств в конструкторе, этап 2
Рассмотрим одно из этих определений детально. Вот новое определение для конструктора Engineer:
function Engineer (name, projs, mach) {
this.base = WorkerBee;
this.base(name, "engineering", projs);
this.machine = mach || "";
}
Предположим, Вы создаёте новый Engineer-объект:
jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
JavaScript выполняет следующее:
Операция new создаёт общий объект и присваивает его свойство __proto__ Engineer.prototype.
Операция new передаёт этот новый объект Engineer-конструктору как значение ключевого слова this.
Конструктор создаёт новое свойство base для этого объекта и присваивает значение конструктора WorkerBee свойству base. Это делает конструктор WorkerBee методом Engineer-объекта.
Поскольку base это метод из Engineer, внутри вызова base JavaScript связывает ключевое слово this с объектом, созданным на Этапе 1. Таким образом, функция WorkerBee в свою очередь передаёт аргументы "Doe, Jane" и ["navigator", "javascript"] в функцию-конструктор Employee. После возвращения из функции-конструктора Employee, функция WorkerBee использует оставшийся аргумент для установки свойства projects.
После возвращения из метода base, конструктор Engineer инициализирует свойство machine объекта значением "belau".
После возвращения из конструктора, JavaScript присваивает новый объект переменной jane.
Имя свойства base не является специальным. Вы может использовать любое верное имя свойства; base просто подходит по смыслу.
Конструктор вызывает метод base, передавая ему в качестве аргументов два аргумента из переданных конструктору ("Doe, Jane" и ["navigator", "javascript"]), а также строку "engineering". Явное использование "engineering" в конструкторе указывает, что все Engineer-объекты имеют одно значение для наследуемого свойства dept, и что это значение переопределяет значение, наследуемое из Employee.
Вы можете подумать, что, вызвав конструктор WorkerBee из конструктора Engineer, Вы установили соответствующее наследование для Engineer-объектов, но это не так. Вызов конструктора WorkerBee гарантирует, что объект Engineer стартует со свойствами, специфицированными во всех функциях-конструкторах, которые вызываются. Однако, если Вы позднее добавите свойства в прототипы Employee или WorkerBee, эти свойства не будут наследоваться объектом Engineer. Например, у Вас имеются операторы:
function Engineer (name, projs, mach) {
this.base = WorkerBee;
this.base(name, "engineering", projs);
this.machine = mach || "";
}
jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
Employee.prototype.specialty = "none";
Объект jane не наследует свойство specialty. Вам всё ещё необходимо явным образом изменить прототип для обеспечения динамического наследования. предположим, что у Вас имеются другие операторы:
function Engineer (name, projs, mach) {
this.base = WorkerBee;
this.base(name, "engineering", projs);
this.machine = mach || "";
}
Engineer.prototype = new WorkerBee;
jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
Employee.prototype.specialty = "none";
Теперь значение свойства specialty объекта jane равно "none".