Чтение онлайн

на главную - закладки

Жанры

JavaScript. Подробное руководство, 6-е издание
Шрифт:

Примечательно, что метод

compareTo
класса
Range
, представленный выше, возвращает 0, когда два диапазона имеют одинаковые нижние границы. Это означает, что в данной реализации метод
сотрагеТо
считает равными любые два диапазона, которые имеют одинаковые нижние границы. Однако такое определение равенства не согласуется с определением, положенным в основу метода
equals,
который требует равенства обеих границ. Подобные несоответствия в определениях равенства могут стать причиной опасных ошибок, и было бы лучше привести методы
equals
и
compareTo
в соответствие друг с другом. Ниже приводится обновленная версия метода
compareTo
класса
Range
. Он соответствует методу
equals
и дополнительно возбуждает исключение при передаче ему несопоставимого значения:

// Порядок следования диапазонов определяется их нижними границами

// или верхними границами, если нижние границы равны.Возбуждает исключение,

// если методу передается объект, не являющийся экземпляром класса Range.

// Возвращает 0, только если this.equals(that) возвращает true.

Range.prototype.compareTo = function(that) {

if (!(that instanceof Range))

throw new Еrror("Нельзя сравнить Range c " + that);

var diff = this.from - that.from; // Сравнить нижние границы

if (diff == 0) diff = this.to - that.to; // Если равны, сравнить верхние

return diff;

};

Одна из причин, по которым может потребоваться сравнивать экземпляры класса, - обеспечить возможность сортировки массива экземпляров этого класса. Метод Array.sort может принимать в виде необязательного аргумента функцию сравнения, которая должна следовать тем же соглашениям о возвращаемом значении, что и метод

compareTo.
При наличии метода
compareTo,
представленного выше, достаточно просто организовать сортировку массива объектов
Range
, как показано ниже:

ranges.sort(function(a,b) { return a.compareTo(b); });

Сортировка имеет настолько большое значение, что следует рассмотреть возможность реализации статического метода сравнения в любом классе, где определен метод экземпляров

compareTo.
Особенно если учесть, что первый может быть легко реализован в терминах второго, например:

Range.byLowerBound = function(a,b) { return a.compareTo(b); };

При наличии этого метода сортировка массива может быть реализована еще проще:

ranges.sort(Range.byLowerBound);

Некоторые классы могут быть упорядочены более чем одним способом. Например, класс

Card
определяет один метод класса, упорядочивающий карты по масти, а другой - упорядочивающий по значению.

9.6.5. Заимствование методов

В методах JavaScript нет ничего необычного - это обычные функции, присвоенные свойствам объекта и вызываемые «посредством» или «в контексте» объекта.

Одна и та же функция может быть присвоена двум свойствам и играть роль двух методов. Мы использовали эту возможность в нашем классе

Set
, например, когда скопировали метод
toArray
и заставили его играть вторую роль в виде метода
toJSON
.

Одна и та же функция может даже использоваться как метод сразу нескольких классов. Большинство методов класса

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

Заимствоваться могут не только методы класса

Array
: мы можем реализовать собственные универсальные методы. В примере 9.9 определяются обобщенные методы
toString
и
equals,
которые с успехом могут использоваться в таких классах, как
Range, Complex
и
Card
. Если бы класс Range не имел собственного метода
equals,
мы могли бы заимствовать обобщенный метод
equals
, как показано ниже:

Range.prototype.equals = generic.equals;

Обратите внимание, что метод

generic.equals
выполняет лишь поверхностное сравнение и не подходит для использования в классах, свойства экземпляров которых ссылаются на объекты с их собственными методами
equals.
Отметьте также, что этот метод включает специальный случай для обработки свойства, добавляемого к объектам при включении их в множество Set (пример 9.6).

Пример 9.9. Обобщенные методы, пригодные для заимствования

var generic = {

// Возвращает строку, включающую имя функции-конструктора, если доступно,

// и имена и значения всех неунаследованных свойств, не являющихся функциями.

toString: function {

var s = '[';

// Если объект имеет конструктор и конструктор имеет имя, использовать

// это имя класса как часть возвращаемой строки. Обратите внимание, что

// свойство name функций является нестандартным и не поддерживается повсеместно,

if (this.constructor && this.constructor.name) s += this.constructor.name + ";

// Теперь обойти все неунаследованные свойства, не являющиеся функциями

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

Первый среди равных

Бор Жорж
1. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Первый среди равных

Ученик

Листратов Валерий
2. Ушедший Род
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Ученик

Рубежник

Билик Дмитрий Александрович
1. Бедовый
Фантастика:
юмористическая фантастика
городское фэнтези
мистика
5.00
рейтинг книги
Рубежник

Ученик. Книга вторая

Первухин Андрей Евгеньевич
2. Ученик
Фантастика:
фэнтези
5.40
рейтинг книги
Ученик. Книга вторая

Телохранитель Генсека. Том 1

Алмазный Петр
1. Медведев
Фантастика:
попаданцы
альтернативная история
7.00
рейтинг книги
Телохранитель Генсека. Том 1

Эволюционер из трущоб. Том 4

Панарин Антон
4. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 4

Я не царь. Книга XXIV

Дрейк Сириус
24. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я не царь. Книга XXIV

Я снова граф. Книга XI

Дрейк Сириус
11. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я снова граф. Книга XI

Вечный. Книга V

Рокотов Алексей
5. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга V

Матабар

Клеванский Кирилл Сергеевич
1. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар

Наномашины, сынок! Том 1

Новиков Николай Васильевич
1. Чего смотришь? Иди книгу читай
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наномашины, сынок! Том 1

Играть... в тебя

Зайцева Мария
3. Звериные повадки Симоновых
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Играть... в тебя

Товарищ "Чума" 4

lanpirot
4. Товарищ "Чума"
Фантастика:
городское фэнтези
альтернативная история
5.00
рейтинг книги
Товарищ Чума 4

Менталист. Эмансипация

Еслер Андрей
1. Выиграть у времени
Фантастика:
альтернативная история
7.52
рейтинг книги
Менталист. Эмансипация