for(var x = Math.ceil(this.from); x <= this.to; x++) f(x);
},
toString: function() { return "(" + this.from + “..." + this.to + }
};
Другой типичный способ заключается в том, чтобы использовать предопределенный объект-прототип, который уже имеет свойство constructor, и добавлять методы в него:
// Здесь расширяется предопределенный объект Range.prototype,
// поэтому не требуется переопределять значение автоматически
// создаваемого свойства Range.prototype.constructor.
Range.prototype.includes = function(x) { return this.from<=x && x<=this.to; };
Range.prototype.foreach = function(f) {
for(var x = Math.ceil(this.from); x <= this.to; x++) f(x);
};
Range.prototype.toString = function() {
return "(" + this, from + "..." + this, to + ")";
};
Если вам приходилось программировать на языке Java или других объектно-ориентированных языках со строгим контролем типов, вы, возможно, привыкли считать, что классы могут иметь четыре типа членов:
Поля экземпляра
Это свойства, или переменные экземпляра, хранящие информацию о конкретном объекте.
Методы экземпляров
Методы, общие для всех экземпляров класса, которые вызываются относительно конкретного объекта.
Поля класса
Это свойства, или переменные, всего класса в целом, а не конкретного экземпляра.
Методы класса
Методы всего класса в целом, а не конкретного экземпляра.
Одна из особенностей языка JavaScript, отличающая его от языка Java, состоит в том, что функции в JavaScript являются значениями, и поэтому нет четкой границы между методами и полями. Если значением свойства является функция, это свойство определяется как метод. В противном случае это обычное свойство, или «поле». Но, несмотря на эти отличия, имеется возможность имитировать все четыре категории членов классов в языке JavaScript. Определение любого класса в языке JavaScript вовлекает три различных объекта (рис. 9.1), а свойства этих трех объектов действуют подобно различным категориям членов класса:
Объект-конструктор
Как уже было отмечено, функция-конструктор (объект) в языке JavaScript определяет имя класса. Свойства, добавляемые в этот объект конструктора, играют роль полей класса и методов класса (в зависимости от того, является ли значение свойства функцией или нет).
Объект-прототип
Свойства этого объекта наследуются всеми экземплярами класса, при этом свойства, значениями которых являются функции, играют роль методов экземпляра класса.
Объект экземпляра
Каждый экземпляр класса - это самостоятельный объект, а свойства, определяемые непосредственно в экземпляре, не являются общими для других экземпляров. Свойства экземпляра, которые не являются функциями, играют роль полей экземпляра класса.
Процесс определения класса в языке JavaScript можно свести к трем этапам. Во-первых, написать функцию-конструктор, которая будет определять свойства экземпляра в новом объекте. Во-вторых, определить методы экземпляров в объекте-прототипе конструктора. В-третьих, определить поля класса и свойства класса в самом конструкторе. Этот алгоритм можно упростить еще больше, определив простую функцию defineClass().
(В ней используется функция extend()
из примера 6.2 с исправлениями из примера 8.3):
// Простая функция для определения простых классов
function defineClass(constructor, // Функция, определяющая свойства экземпляра
methods, // Методы экземпляров: копируются в прототип
statics) // Свойства класса: копируются в конструктор
{
if (methods) extend(constructor.prototype, methods);
if (statics) extend(constructor, statics);
return constructor;
}
// Простейший вариант нашего класса Range
var SimpleRange =
defineClass(function(f,t) { this.f = f; this.t = t; },
{
includes: function(x) { return this.f<=x && x <= this.t;},
toString: function() { return this.f + "..." + this.t; }
},
{ upto: function(t) { return new SimpleRange(0, t); } });
В примере 9.3 приводится более длинное определение класса. В нем создается класс, представляющий комплексные числа, и демонстрируется, как имитировать члены класса в стиле Java. Здесь все делается «вручную» - без использования функции defineClass(),
представленной выше.
Читать дальше
Конец ознакомительного отрывка
Купить книгу