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

<b>  // но также с текстовыми диапазонами и с диапазонами дат Date,</b>

<b>  includes: function(x) { return this.from &lt;= x &amp;&amp; x &lt;= this.to; },</b>

<b>  // Вызывает f для каждого целого числа в диапазоне.</b>

<b>  // Этот метод может работать только с числовыми диапазонами,</b>

<b>  foreach: function(f) {</b>

<b>    for(var х = Math.ceil(this.from); x &lt;= this.to; x++) f(x);</b>

<b>  }</b>

<b>  // Возвращает строковое представление диапазона</b>

<b>  toString: function() { return &quot;(&quot; + this.from + &quot;...&quot; + this.to + &quot;)&quot; }</b>

<b>}</b>

<b>// Ниже приводится пример использования объекта range.</b>

<b>var r = range(1,3);    </b><div class="fb2-code"><code>&lt;b&gt;// Создать новый объект range &lt;/b&gt;</code></div>

<b>r.includes(2);         </b><div class="fb2-code"><code>&lt;b&gt;// =&amp;gt; true: число 2 входит в диапазон &lt;/b&gt;</code></div>

<b>r.foreach(console.log);</b><div class="fb2-code"><code>&lt;b&gt;// Выведет 1 2 3 &lt;/b&gt;</code></div>

<b>console.log(r);        </b>
<b>// Выведет (1...3)</b>

В примере 9.1 есть несколько интересных моментов, которые следует отметить особо. Здесь определяется фабричная функция

<b>range(),</b>
которая используется для создания новых объектов
<b>range</b>
. Обратите внимание, что для хранения объекта-прототипа, определяющего класс, используется свойство
<b>range.methods</b>
функции
<b>range().</b>
В таком способе хранения объекта-прототипа нет ничего необычного. Во-вторых, отметьте, что функция
<b>range()</b>
определяет свойства
<b>from</b>
и
<b>to</b>
для каждого объекта
<b>range</b>
. Эти не общие, не унаследованные свойства определяют уникальную информацию для каждого отдельного объекта range. Наконец, обратите внимание, что все общие, унаследованные методы, определяемые свойством
<b>range.methods</b>
, используют свойства
<b>from</b>
и
<b>to</b>
и ссылаются на них с помощью ключевого слова
<b>this</b>
, указывающего на объект, относительно которого вызываются эти методы. Такой способ использования this является фундаментальной характеристикой методов любого класса.

9.2. Классы и конструкторы

В примере 9.1 демонстрируется один из способов определения класса в языке JavaScript. Однако это не самый типичный способ, потому что он не связан с определением конструктора. Конструктор - это функция, предназначенная для инициализации вновь созданных объектов. Как описывалось в разделе 8.2.3, конструкторы вызываются с помощью ключевого слова

<b>new</b>
. Применение ключевого слова
<b>new</b>
при вызове конструктора автоматически создает новый объект, поэтому конструктору остается только инициализировать свойства этого нового объекта. Важной особенностью вызова конструктора является использование свойства
<b>prototype</b>
конструктора в качестве прототипа нового объекта. Это означает, что все объекты, созданные с помощью одного конструктора, наследуют один и тот же объект-прототип и, соответственно, являются членами одного и того же класса. В примере 9.2 демонстрируется, как можно было бы реализовать класс
<b>range</b>
, представленный в примере 9.1, не с помощью фабричной функции, а с помощью функции конструктора:

Пример 9.2. Реализация класса Range с помощью конструктора

<b>// range2.js: Еще один класс, представляющий диапазон значений.</b>

<b>// Это функция-конструктор, которая инициализирует новые объекты Range.</b>

<b>// Обратите внимание, что она не создает и не возвращает объект.</b>

<b>// Она лишь инициализирует его. </b>

<b>function Range(from, to) {</b>

<b>  // Сохранить начальное и конечное значения в новом объекте range.</b>

<b>  // Это не унаследованные свойства, и они являются уникальными для данного объекта, </b>

<b>  this.from = from; </b>

<b>  this.to = to;</b>

<b>}</b>

<b>// Все объекты Range наследуют свойства этого объекта.</b>

<b>// Обратите внимание, что свойство обязательно должно иметь имя &quot;prototype&quot;.</b>

<b>Range.prototype = {</b>

<b>  // Возвращает true, если х - объект класса range, в противном случае возвращает false </b>

<b>  // Этот метод может работать не только с числовыми диапазонами, но также </b>

<b>  // с текстовыми диапазонами и с диапазонами дат Date, </b>

<b>  includes: function(x) { return this.from &lt;= x &amp;&amp; x &lt;= this.to; },</b>

<b>  // Вызывает f для каждого целого числа в диапазоне.</b>

<b>  // Этот метод может работать только с числовыми диапазонами, </b>

<b>  foreach: function(f) {</b>

<b>    for(var х = Math.ceil(this.from); x &lt;= this.to; x++) f(x);</b>

<b>  },</b>