Вход/Регистрация
JavaScript. Подробное руководство, 6-е издание
вернуться

Флэнаган Дэвид

Шрифт:

Наконец, обратите также внимание на одинаковые фрагменты примеров 9.1 и 9.2: в обоих классах методы объекта range определяются и вызываются одинаковым способом.

9.2.1. Конструкторы и идентификация класса

Как видите, объект-прототип играет чрезвычайно важную роль в идентификации класса: два объекта являются экземплярами одного класса, только если они наследуют один и тот же объект-прототип. Функция-конструктор, инициализирующая свойства нового объекта, не является определяющей: два конструктора могут иметь свойства

prototype
, ссылающиеся на один объект-прототип. В этом случае оба конструктора будут создавать экземпляры одного и того же класса.

Хотя конструкторы не играют такую же важную роль в идентификации класса, как прототипы, тем не менее конструкторы выступают в качестве фасада класса. Например, имя конструктора обычно используется в качестве имени класса. Так, принято говорить, что конструктор

Range
создает объекты класса
Range
. Однако более важным применением конструкторов является их использование в операторе
instanceof
при проверке принадлежности объекта классу. Если имеется объект r, и необходимо проверить, является ли он объектом класса
Range
, такую проверку можно выполнить так:

r instanceof Range // вернет true, если r наследует Range.prototype

В действительности оператор

instanceof
не проверяет, был ли объект r инициализирован конструктором
Range
. Он проверяет, наследует ли этот объект свойство
Range.prototype
. Как бы то ни было, синтаксис оператора
instanceof
закрепляет использование конструкторов в качестве идентификаторов классов. Мы еще встретимся с оператором
instanceof
далее в этой главе.

9.2.2. Свойство constructor

В примере 9.2 свойству

Range.prototype
присваивался новый объект, содержащий методы класса. Хотя было удобно определить методы как свойства единственного объекта-литерала, но при этом совершенно не было необходимости создавать новый объект. Роль конструктора в языке JavaScript может играть любая функция, поскольку выражению вызова конструктора необходимо лишь свойство
рrototype
. Следовательно, любая функция (кроме функций, возвращаемых методом
Function.bind
в ECMAScript 5) автоматически получает свойство
prototype
. Значением этого свойства является объект, который имеет единственное неперечислимое свойство
constructor
. Значением свойства
constructor
является объект функции:

var F = function {};
// Это объект функции.

var р = F.prototype;
// Это объект-прототип, связанный с ней.

var c = p.constructor;
// Это функция, связанная с прототипом.

c === F
// => true: F.prototype.constructor === F для всех функций

Наличие предопределенного объекта-прототипа со свойством

constructor
означает, что объекты обычно наследуют свойство
constructor
, которое ссылается на их конструкторы. Поскольку конструкторы играют роль идентификаторов классов, свойство
constructor
определяет класс объекта:

var о = new F; // Создать объект класса F

о.constructor === F // => true: свойство constructor определяет класс

Эти взаимосвязи между функцией-конструктором, ее прототипом, обратной ссылкой из прототипа на конструктор и экземплярами, созданными с помощью конструктора, иллюстрируются на рис. 9.1.

Обратите внимание, что в качестве примера для рис. 9.1 был взят наш конструктор

Range.
Однако в действительности класс
Range
, определенный в примере 9.2, замещает предопределенный объект
Range.prototype
своим собственным. А новый объект-прототип не имеет свойства
constructor
. По этой причине экземпляры класса
Range
, как следует из определения, не имеют свойства
constructor
. Решить эту проблему можно, явно добавив конструктор в прототип:

Range.prototype = {

constructor: Range, // Явно установить обратную ссылку на конструктор

includes: function(x) { return this.from <= x && x <= this.to; },

foreach: function(f) {

for(var x = Math.ceil(this.from); x <= this.to; x++) f(x);

},

  • Читать дальше
  • 1
  • ...
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: