Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Язык программирования javascript 16.02.12.doc
Скачиваний:
7
Добавлен:
31.08.2019
Размер:
2.86 Mб
Скачать

Определение взаимоотношений экземпляров

Возможно, Вы захотите узнать, какие объекты находятся в цепочке прототипов данного объекта, чтобы определить, из какого объекта данный объект наследует свойства. В языках на базе классов Вы можете использовать для этого операцию instanceof. В JavaScript нетinstanceof, но Вы сами можете написать такую функцию.

Как сказано в "Наследовании Свойств", если Вы используете операцию new с функцией-конструктором для создания новых объектов, JavaScript устанавливает в свойство __proto__нового объекта значение свойства prototype функции-конструктора. Вы можете использовать это для проверки цепочки прототипов.

Например, у Вас есть уже показанный ранее набор определений с соответственно установленными прототипами. Создайте объект __proto__ так:

chris = new Engineer("Pigman, Chris", ["jsd"], "fiji");

С эти объектом все следующие операторы true:

chris.__proto__ == Engineer.prototype; chris.__proto__.__proto__ == WorkerBee.prototype; chris.__proto__.__proto__.__proto__ == Employee.prototype; chris.__proto__.__proto__.__proto__.__proto__ == Object.prototype; chris.__proto__.__proto__.__proto__.__proto__.__proto__ == null;

Имея это, Вы можете написать функцию instanceOf:

function instanceOf(object, constructor) { while (object != null) { if (object == constructor.prototype) return true; object = object.__proto__; } return false; }

При таком определении все следующие выражения true:

instanceOf (chris, Engineer) instanceOf (chris, WorkerBee) instanceOf (chris, Employee) instanceOf (chris, Object)

Но следующее выражение будет false:

instanceOf (chris, SalesPerson)

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

При создании конструкторов Вы должны быть осторожны, если устанавливаете глобальную информацию в конструкторе. Например, у Вас имеется уникальный идентификатор 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, Вы обязаны специфицировать имя employee. В данном примере, mac.id может быть 1.