Ядро JavaScript 1.5. Руководство по использованию

Глобальная Информация в Конструкторах


Когда Вы создаёте конструкторы, нужно проявлять осторожность при установке глобальной информации в конструкторе. Например, предположим, Вы хотите автоматически присваивать уникальный 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.





Содержание раздела