Книга: JavaScript. Подробное руководство, 6-е издание
9.8.5. Подклассы и ECMAScript 5
9.8.5. Подклассы и ECMAScript 5
В примере 9.22 демонстрируется порядок создания подклассов с использованием возможностей ECMAScript 5. В нем определяется класс stringSet,
наследующий класс AbstractWritableSet
из примера 9.16. Основная особенность этого примера заключается в использовании функции Object.сreate()
для создания объекта-прототипа, наследующего прототип суперкласса, и в определении свойств вновь созданного объекта. Как уже отмечалось выше, основная сложность этого подхода заключается в необходимости использовать неудобные дескрипторы свойств.
Другой интересной особенностью этого примера является передача значения null функции Object.сreate()
при создании объекта, не наследующего ничего. Этот объект используется для хранения элементов множества, а тот факт, что он не имеет прототипа, позволяет вместо метода hasOwnProperty()
использовать оператор in
.
Пример 9.22. StringSet
: определение подкласса множества с использованием ECMAScript 5
function StringSet() {
this.set = Object.create(null); // Создать объект без прототипа
this.n = 0;
this.add.apply(this, arguments);
}
// Обратите внимание, что Object.create позволяет обеспечить наследование
// прототипа суперкласса и определить методы за счет единственного вызова.
// Поскольку при создании свойств мы не указываем значения атрибутов writable,
// enumerable и configurable, они по умолчанию получают значение false.
// Доступность методов только для чтения усложняет их переопределение в подклассах.
StringSet.prototype = Object.create(AbstractWritableSet.prototype, {
constructor: { value: StringSet },
contains: { value: function(x) { return x in this.set; } }.
size: { value: function(x) { return this.n; } },
foreach: { value: function(f,c) { Object.keys(this.set).forEach(f.c); } }.
add: {
value: function() {
for(var і = 0; і < arguments.length; i++) {
if (!(arguments[i] in this.set)) {
this.set[arguments[i]] = true;
this.n++;
}
}
return this;
}
),
remove: {
value: function() {
for(var і = 0; і < arguments.length; i++){
if (arguments[i] in this.set) {
delete this.set[arguments[i]];
this, n--;
}
}
return this;
}
}
});