9.8.3. Сокрытие данных объекта

We use cookies. Read the Privacy and Cookie Policy

В разделе 9.6.6 и в примере 9.10 было показано, как можно использовать переменные и аргументы функции-конструктора для сокрытия данных объекта, создаваемого этим конструктором. Недостаток этого приема заключается в том, что в ECMAScript 3 допускается возможность замещения методов доступа к этим данным. Стандарт ECMAScript 5 позволяет обеспечить более надежное сокрытие частных данных за счет определения методов доступа к свойствам, которые не могут быть удалены. Этот способ демонстрируется в примере 9.21.

Пример 9.21. Класс Range со строго инкапсулированными границами

// Эта версия класса Range является изменяемой, но она следит за своими

// границами, обеспечивая выполнение условия from <= to.

function Range(from, to) {

  // Проверить соблюдение условия при создании

  if (from > to) throw new Error("Range: значение from должно быть <= to");

  // Определение методов доступа, которые следят за соблюдением условия

  function getFrom() { return from; }

  function getTo() { return to; }

  function setFrom(f) { // He позволяет устанавливать значение from > to

    if (f <= to) from = f;

    else throw new Error("Range: значение from должно быть <= to");

  }

  function setTo(t) { // He позволяет устанавливать значение to < from

    if (t >= from) to = t;

    else throw new Error("Range: значение to должно быть >= from");

  }

  // Создать перечислимые, ненастраиваемые свойства с методами доступа

  Object.defineProperties(this, {

    from: {getigetFrom,

      set:setFrom,

      enumerable:true,

      configurable:false},

    to: { get: getTo,

      set: setTo,

      enumerable:true,

      configurable:false }

  });

}

// Настройка объекта-прототипа осталась такой же, как и в предыдущих примерах.

// Обращение к методам экземпляров чтения свойств from и to выполняется так,

// как если бы они были простыми свойствами.

Range.prototype = hideProps({

  constructor: Range,

  includes: function(x) {

    return this.from <= x && x <= this.to: },

  foreach: function(f) {

    for(var x=Math.ceil(this.from);x<=this.to;x++) f(x);},

  toString: function() { return "(" + this, from + ”..." + this, to + ")"; }

});