Полезны ли в JavaScript простые методы поиска и назначения? - PullRequest
0 голосов
/ 18 сентября 2018

Есть ли смысл повторять этот шаблон для каждого свойства в JavaScript?

class Thing {
  get myProp() {
    return this._myProp;
  }
  set myProp(value) {
    this._myProp = value;
  }
}

Я понимаю, что методы получения / установки могут быть полезны, если вы выполняете дополнительную работу с методами, но воссоздаете базовыефункциональность здесь кажется ненужным повторением.Если я инстанцирую, я все еще могу напрямую манипулировать свойством поддержки (._myProp), поэтому я чувствую, что могу так же легко их пропустить и выполнить свое назначение и доступ более типичным, специальным способом.

Полагаю, вы могли бы утверждать, что определение интерфейса таким образом (с именем свойства с префиксом подчеркивания) сигнализирует пользователям, что оно не предназначено для манипулирования свойством, но это кажется неубедительной причиной для потенциально десятков из них.

Ответы [ 4 ]

0 голосов
/ 18 сентября 2018

Если я создаю экземпляр, я все еще могу напрямую манипулировать свойством поддержки (._myProp),

Если частные состояния - это то, что вы ищете, вы все равно можете использовать слабую карту.

(function(scope) {
  "use strict";
  const prop = new WeakMap();

  scope.Foo = class {
    constructor() {
      prop.set(this, {});
      Object.seal(this);
    }
    get bar() {
      return prop.get(this)._bar;
    }
    set bar(value) {
      return prop.get(this)._bar = value;
    }
  }


}(this))

const f = new Foo;

f.bar = "bar";
f._bar = "_bar";
console.log(f.bar);
console.log(f._bar);

get и setters также полезны при реализации MVC, вы можете запускать события при изменении свойства.

(function(scope) {
  "use strict";
  const prop = new WeakMap();

  scope.Foo = class {
    constructor() {
      prop.set(this, {});
      prop.get(this)._target = new EventTarget
      Object.seal(this);
    }
    get bar() {
      return prop.get(this)._bar;
    }
    set bar(value) {
      prop.get(this)._bar = value;
      prop.get(this)._target.dispatchEvent(new CustomEvent('change', {
        detail: value
      }));
    }
    addEventListener(event, listener) {
      prop.get(this)._target.addEventListener(event, listener)
    }
  }


}(this))

const f = new Foo;
f.addEventListener('change', function(event) {
  console.log("changed!", event.detail);
});
f.bar = "bar";
0 голосов
/ 18 сентября 2018

Средства доступа к свойствам полезны для предоставления побочных эффектов или изменения исходного поведения:

class Thing {
  get myProp() {
    console.log('myProp was read');
    return this._myProp;
  }
  set myProp(value) {
    if (!value)
      throw new Error('myProp cannot be falsy');
    this._myProp = value;
  }
}

Нет смысла в myProp чистой абстракции геттера / сеттера:

class Thing {
  get myProp() {
    return this._myProp;
  }
  set myProp(value) {
    this._myProp = value;
  }
}
0 голосов
/ 18 сентября 2018

На скомпилированных языках люди обычно делают это.Это связано с тем, что в этих языках назначение поля и вызов метода установки могут быть идентичны программисту, но они компилируются в две совершенно разные операции.

Если я хотел добавить побочный эффект для установки поля вкласс C #, например, и это поле устанавливалось напрямую, а не через установщик?Изменение его на сеттер может вызвать некоторые проблемы.Мне не пришлось бы переписывать какой-либо код потребления, но мне бы пришлось бы перекомпилировать все это.Это, конечно, огромная проблема, если ваши публичные выпуски скомпилированы.

Однако JavaScript не подлежит таким соображениям, поэтому преждевременное превращение всего в метод получения / установки является глупым.Если вы видите, что кто-то делает это, скорее всего, вы имеете дело с кем-то, кто выучил соглашение на другом языке и перенес его в JavaScript, не задумываясь о почему.

0 голосов
/ 18 сентября 2018

Использование свойства аксессора описанным вами способом (установка и получение свойства данных «фона») практически семантически идентично использованию свойства данных напрямую.Существуют некоторые различия: свойство accessor будет существовать в прототипе экземпляра, а не непосредственно в экземпляре (хотя экземпляр будет иметь свойство данных «background»), но это на самом деле ни на что не повлияет, если вы не выполните расширенный самоанализэкземпляры класса.

Единственным преимуществом является простота изменения кода, если вы хотите ввести более изощренное поведение средства доступа в будущем.Если вы предвидите необходимость добавить поведение аксессора, используйте этот шаблон, чтобы сэкономить время в будущем.

...