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

<b>*/</b>

<b>var AbstractEnumerableSet = AbstractSet.extend(</b>

<b>  function() {</b>

<b>    throw new Error(&quot;Нельзя создать экземпляр абстрактного класса&quot;);</b>

<b>  },</b>

<b>  {</b>

<b>    size: abstractmethod,</b>

<b>    fоreach: abstractmethod,</b>

<b>    isEmpty: function() { return this.size() == 0; },</b>

<b>    toString: function() {</b>

<b>      var s = і = 0;</b>

<b>      this.foreach(function(v) {</b>

<b>          if (i++ &gt; 0) s += &quot;, &quot;;</b>

<b>          s += v;</b>

<b>      });</b>

<b>      return s +</b>

<b>    },</b>

<b>    toLocaleString : function() { </b>

<b>      var s = &quot;{&quot;, і = 0;</b>

<b>      this.foreach(function(v) {</b>

<b>        if (i++ &gt; 0) s += &quot;, &quot;</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>    toArray: function() {</b>

<b>      var a = [];</b>

<b>      this.foreach(function(v) { a.push(v); });</b>

<b>      return a;</b>

<b>    },</b>

<b>    equals: function(that) {</b>

<b>      if (!(that instanceof AbstractEnumerableSet)) return false;</b>

<b>      // Если множество that имеет другой размер, множества не равны</b>

<b>      if (this.size() ! = that.sizeO) return false;</b>

<b>      // Проверить наличие каждого элемента this в множестве that,</b>

<b>      try {</b>

<b>        this.foreach(function(v){</b>

<b>          if (!that.contains(v)) throw false;}</b>

<b>        );</b>

<b>        return true; // Все элементы одинаковые: множества равны.</b>

<b>      } catch (х) {</b>

<b>        if (х === false) return false; // Множества не равны</b>

<b>        throw х; // Повторно возбудить любое иное возникшее исключение.</b>

<b>      }</b>

<b>    }</b>

<b>  });</b>

<b>/*</b>

<b>* SingletonSet - конкретный подкласс класса AbstractEnumerableSet.</b>

<b>* Множество из единственного элемента, доступное только для чтения.</b>

<b>*/</b>

<b>var SingletonSet = AbstractEnumerableSet.extend(</b>

<b>  function SingletonSet(member) { this.member = member; },</b>

<b>  {</b>

<b>    contains: function(x) { return x === this.member; },</b>

<b>    size: function() { return 1; },</b>

<b>    foreach: function(f,ctx) { f.call(ctx, this.member); }</b>

<b>  }</b>

<b>);</b>

<b>/*</b>

<b> * AbstractWritableSet - абстрактный подкласс класса AbstractEnumerableSet.</b>

<b> * Определяет абстрактные методы add() и remove() и реализует конкретные</b>

<b> * методы union(), intersection() и difference().</b>

<b>*/</b>

<b>var AbstractWritableSet = AbstractEnumerableSet.extend(</b>

<b>  function() {</b>

<b>    throw new Error(&quot;Нельзя создать экземпляр абстрактного класса&quot;);</b>

<b>  },</b>

<b>  {</b>

<b>    add: abstractmethod,</b>

<b>    remove: abstractmethod,</b>

<b>    union: function(that) {</b>

<b>      var self = this;</b>

<b>      that.foreach(function(v) { self.add(v); });</b>

<b>      return this;</b>

<b>    },</b>

<b>    intersection: function(that) {</b>

<b>      var self = this;</b>

<b>      this.foreach(function(v){</b>

<b>        if(!that.contains(v)) self.remove(v);</b>

<b>      });</b>