Когда Вы создаёте конструкторы, нужно проявлять осторожность при установке глобальной информации в конструкторе. Например, предположим, Вы хотите автоматически присваивать уникальный ID каждому новому employee. Вы можете использовать для Employee следующее определение:
var idCounter = 1;
function Employee (name, dept) {
this.name = name "";
this.dept = dept "general";
this.id = idCounter++;
}
При таком определении, когда Вы создаёте новый Employee-объект, конструктор присваивает ему следующий порядковый ID и выполняет затем инкремент глобального счётчика ID. Так, если Ваш следующий оператор будет таким, как ниже, victoria.id будет 1, а harry.id будет 2:
victoria = new Employee("Pigbert, Victoria", "pubs")
harry = new Employee("Tschopik, Harry", "sales")
На первый взгляд - всё отлично. Однако idCounter будет увеличиваться каждый раз при создании Employee-объекта. Если Вы создаёте всю иерархию Employee, данную в этой главе, конструктор Employee вызывается каждый раз, когда Вы устанавливаете прототип. Предположим, у Вас есть такой код:
var idCounter = 1;
function Employee (name, dept) {
this.name = name "";
this.dept = dept "general";
this.id = idCounter++;
}
function Manager (name, dept, reports) {...}
Manager.prototype = new Employee;
function WorkerBee (name, dept, projs) {...}
WorkerBee.prototype = new Employee;
function Engineer (name, projs, mach) {...}
Engineer.prototype = new WorkerBee;
function SalesPerson (name, projs, quota) {...}
SalesPerson.prototype = new WorkerBee;
mac = new Engineer("Wood, Mac");
Предположим далее, что отсутствующие здесь определения имеют свойство base и вызывают конструктор, находящийся над ним в цепи прототипов. В этом случае, когда создаётся объект mac, mac.id будет 5.
В зависимости от приложения, такое излишнее увеличение счётчика может иметь или не иметь значения. Если Вас интересует точное значение счётчика, реализуется ещё одно дополнительное решение путём использования следующего конструктора:
function Employee (name, dept) {
this.name = name "";
this.dept = dept "general";
if (name)
this.id = idCounter++;
}
Если Вы создаёте экземпляр объекта Employee для использования в качестве прототипа, Вы не должны предоставлять аргументы конструктору. Если Вы используете это определение конструктора и не предоставляете аргументы, конструктор не присваивает значение идентификатору id и не обновляет значение счётчика. Следовательно, для того чтобы Employee получил присвоенный id, Вы обязаны специфицировать name для employee. В этом примере, mac.id будет 1.