Шрифт:
Пример 9.7 Типы-перечисления в JavaScript
// Эта функция создает новый тип-перечисление. Объект в аргументе определяет
// имена и значения каждого экземпляра класса. Возвращает функцию-конструктор,
// идентифицирующую новый класс. Отметьте, однако, что конструктор возбуждает
// исключение: его нельзя использовать для создания новых экземпляров типа.
// Возвращаемый конструктор имеет свойства, которые отображают имена в значения,
// а также массив значений values и функцию foreach для выполнения итераций
function enumeration(namesToValues) {
// Фиктивный конструктор, который будет использоваться как
// возвращаемое значение.
var enumeration = function { throw "Нельзя создать экземпляр класса” +
Enumeration"; };
// Перечислимые значения наследуют объект this,
var proto = enumeration.prototype = {
constructor: enumeration, // Идентификатор типа
toString: function { return this.name; }, // Возвращает имя
valueOf: function { return this.value; }, // Возвращает значение
toJSON: function { return this.name; } // Для сериализации
};
enumeration.values = []; // Массив перечислимых объектов-значений
// Теперь создать экземпляры нового типа.
for(name in namesToValues) { // Для каждого значения
var е = inherit(proto); // Создать объект для его представления
e.name = name; // Дать ему имя
е.value = namesToValues[name]; // И значение
enumeration[name] = е; // Сделать свойством конструктора
enumeration.values.push(e); // И сохранить в массиве values
}
// Метод класса для обхода экземпляров класса в цикле
enumeration.foreach = function(f,с) {
for(var і = 0; і < this.values.length; i++) f.call(c,this.values[i]);
};
// Вернуть конструктор, идентифицирующий новый тип
return enumeration;
}
Типичным начальным примером использования типов-перечислений может служить реализация перечисления для представления колоды игральных карт. Пример 9.8 использует функцию enumeration) именно для этого, а также определяет классы для представления карт и колод карт. [16]
16
Этот пример основан на примере для языка Java, написанном Джошуа Блохом (Joshua Bloch) и доступном по адресу:
Пример 9.8. Представление игральных карт в виде типов-перечислений
// Определение класса для представления игральной карты
function Card(suit, rank) {
this.suit = suit; // Каждая карта имеет масть
this.rank = rank; // и значение
}
// Следующие типы-перечисления определяют возможные масти и значения карт
Card.Suit = enumeration({Clubs: 1, Diamonds: 2, Hearts:3, Spades:4});
Card.Rank = enumeration({Two: 2, Three: 3, Four: 4, Five: 5, Six: 6,
Seven: 7, Eight: 8, Nine: 9, Ten: 10,
Jack: 11, Queen: 12, King: 13, Ace: 14});
// Определение текстового представления карты
Card.prototype.toString = function {