Третьим методом является метод
<b>valueOf().</b>
Его цель - преобразовать объект в простое значение. Метод
<b>valueOf()</b>
вызывается автоматически, когда объект используется в числовом контексте, например, с арифметическими операторами (отличными от
<b>+</b>
) и с операторами отношения. Большинство объектов не имеют сколько-нибудь осмысленного простого представления и потому не определяют этот метод. Однако типы-перечисления в примере 9.7 представляют случай, когда метод
<b>valueOf()</b>
имеет большое значение.
Четвертый метод -
<b>toJSON()</b>
- вызывается автоматически функцией
<b>JSON.stringifу().</b>
Формат JSON предназначен для сериализации структур данных и может использоваться для представления простых значений, массивов и простых объектов. При преобразовании в этот формат не делается никаких предположений о классах, и при сериализации объекта игнорируются его прототип и конструктор. Если вызвать функцию
<b>JSON.stringify()</b>
для сериализации объекта
<b>Range</b>
или
<b>Complex</b>
, например, она вернет строку вида
<b>{"from”: 1, ”to":3}</b>
или
<b>{"r":1, "i":-1}.</b>
Если передать такую строку функции
<b>JSON.parse(),</b>
она вернет простой объект со свойствами, соответствующими объекту
<b>Range</b>
или
<b>Complex</b>
, но не наследующий методы класса
<b>Range</b>
или
<b>Complex</b>
.
Такой формат сериализации вполне подходит для классов, таких как
<b>Range</b>
и
<b>Complex</b>
, но для более сложных классов может потребоваться написать собственный метод
<b>toJSON(),</b>
чтобы определить иной формат сериализации. Если объект имеет метод
<b>toJSON(),</b>
функция
<b>JSON.stringify()</b>
не будет выполнять сериализацию самого объекта, а вызовет метод
<b>toJSON()</b>
и произведет сериализацию значения (простого значения или объекта), которое он вернет. Например, объекты
<b>Date</b>
имеют собственный метод
<b>toJSON(),</b>
возвращающий строковое представление даты. Типы-перечисления в примере 9.7 делают то же самое: их метод
<b>toJS0N()</b>
возвращает то же значение, что и метод
<b>toString().</b>
Самым близким к представлению множества в формате JSON является массив, поэтому ниже мы определим метод
<b>toJSON(),</b>
который будет преобразовывать объект
<b>Set</b>
в массив значений.
Класс
<b>Set</b>
, представленный в примере 9.6, не определяет ни один из этих методов. Множество не может быть представлено простым значением, поэтому нет смысла определять метод
<b>valueOf(),</b>
но было бы желательно определить в этом классе методы
<b>toString(), toLocaleString()</b>
и
<b>toJSON().</b>
Можно это сделать, как показано ниже. Обратите внимание, что для добавления методов в
<b>Set.prototype</b>
используется функция
<b>extend()</b>
(пример 6.2):
<b>// Добавить новые методы в объект-прототип класса Set.</b>
<b>extend(Set.prototype, {</b>
<b> // Преобразует множество в строку</b>
<b> toString : </b>
<b>function() {</b>
<b> var s = "{", i = 0;</b>
<b> this.foreach(function(v){ s += ((i++ > 0)?", + ":"") +v });</b>
<b> return s + "}";</b>
<b> }</b>
<b> // Действует так же, как toString, но вызывает toLocaleString</b>
<b> // для всех значений</b>
<b> toLocaleString : </b>
<b>function() {</b>
<b> var s = "{", і = 0;</b>
<b> this.foreach(function(v){</b>
<b> if (i++ > 0)</b>
<b> s += ", ";</b>
<b> if (v == null) s += v; // null и undefined </b>
<b> else s += v. toLocaleString(); // остальные</b>
<b> });</b>
<b> return s +</b>
<b> },</b>
<b> // Преобразует множество в массив значений </b>
<b> toArray : </b>
<b>function() {</b>
<b> var a = [];</b>
<b> this.foreach(function(v) { a.push(v); });</b>
<b> return a;</b>
<b> }</b>
<b>});</b>
<b>// Для нужд сериализации в формат JS0N интерпретировать множество как массив.</b>
<b>Set.prototype.toJSON = Set.prototype.toArray;</b>
9.6.4. Методы сравнения
Операторы сравнения в языке JavaScript сравнивают объекты по ссылке, а не по значению. Так, если имеются две ссылки на объекты, то выясняется, ссылаются они на один и тот же объект или нет, но не выясняется, обладают ли разные объекты одинаковыми свойствами с одинаковыми значениями.[17] Часто бывает удобным иметь возможность сравнить объекты на равенство или определить порядок их следования (например, с помощью операторов отношения
<b><</b>
и
<b>></b>
). Если вы определяете новый класс и хотите иметь возможность сравнивать экземпляры этого класса, вам придется определить соответствующие методы, выполняющие сравнение.