【问题标题】:Class enumeration setter, convention javascript类枚举setter,约定javascript
【发布时间】:2017-09-10 12:06:23
【问题描述】:

您好,我有以下课程:

const MyClass = function MyClass() {
  this.state = null;
}

MyClass.prototype.set = function(key, value) {
    this[key] = value;
}

以及其他模块中的以下枚举:

const enumeration = {
    ACTIVE: 'active',
    PENDING: 'pending',
    DONE: 'done'
}

我想知道处理枚举属性的 setter 的最佳实践/约定是什么(在此处说明)

我可以这样做:

let myClass = new MyClass();
myClass.set('state', enumeration.PENDING);

但它有点冗长,我需要了解 myClass 模块和 enum 模块。
另一个想法是这样做:

const MyClass function MyClass() {
    this.state = null;
}

MyClass.prototype.setPending = function() {
    this.state = enumeration.PENDING;
}

并允许拨打myClass.setPending() 但是我不知道这种setter的正确命名。

【问题讨论】:

  • 三个观察/问题: 1. 在const MyClass 之后您缺少=(为什么不直接使用class,因为您已经清楚地使用了ES2015+ 语法?)。 2.set方法的意义何在? 3.enumfuture reserved word,不能作为标识符使用。
  • 到底是做myClass.set('state', yourenum.PENDING)还是myClass.setPending()完全是见仁见智和风格的问题。这类问题对 SO 来说是题外话。
  • 1-(已编辑)拼写错误。 2- ES6 类只是语法糖。 3-(已编辑)拼写错误。我认为这不是风格问题,而是建模和架构问题。
  • 什么架构?这只是一个类,只是一个属性。关于命名属性和有枚举与没有枚举的讨论是真正的primary opinion based 事情。
  • 我更喜欢.setState(enum.PENDING),然后是.getState() === enum.PENDING。枚举应该是符号

标签: javascript oop enums convention


【解决方案1】:

首先,我认为这个问题不是基于意见的,而是基于需求的。如果您说它是基于偏好的,那意味着您根本没有遇到建立最佳实践来避免的问题。考虑到这一点,第一个最佳实践是使其尽可能简单。您的 API 如何演变取决于您的应用程序的特定需求以及您发现最合适的需求的能力。

以下是 Web FTP 客户端上传对象的“代码演变”示例。请注意,有很多不同的可能路径。此示例的唯一目的是证明最佳实践不仅仅是偏好问题。

你从这个开始:

function Upload(state) {
  this.state = state || 'pending';
  this.elem = document.createElement('div');
}
new Upload().state = 'active';

然后你意识到你需要一个进度条视图在设置状态时更新,所以你制作了一个专门的设置器:

Upload.prototype.setState = function(value) {
  this.state = value;
  this.elem.className = 'state-' + this.state;
};

但是,稍后您决定需要显示通知,但前提是状态设置为“完成”。或者,也许您发现自己需要一种速记方法,因为您必须经常输入 upload.setState('done'),并且发现输入 upload.setStateDone() 更容易(参见 jQuery 的 $.get$.ajax)。

Upload.prototype.setStateDone = function() {
  this.setState('done');
  // code to execute only when the state changes to 'done'
};

请注意,您可以更喜欢一致的 API 而非便利性(例如,我更喜欢 $.get 而不是 $.ajax,因为使用后者会有很大的开销,但我更喜欢使用 jQuery 的 $(elem).on('click',.. 而不是 $.click,因为所有这些确实是预填充“点击”字符串)。

setter 仍然存在问题:如果您设置了无效状态,例如'whatever',它将附加类'state-whatever',所以你更新setState

Upload.prototype.setState = function(value) {
  if (['active', 'pending', 'done'].indexOf(value) > -1)
    this.state = value;
  this.elem.className = 'state-' + this.state;
};

问题是,您的状态在方法中是硬编码的,您希望在其他组件中重新使用它们,因此您定义了状态映射并调整 setState。为了避免硬依赖,您使用依赖注入而不是在构造函数中引用全局 states 映射:

var states = {
  ACTIVE: 'active',
  PENDING: 'pending',
  DONE: 'done'
};

function Upload(state, states) {
  this.states = states;
  this.state = state || this.states.PENDING;
  this.elem = document.createElement('div');
}

Upload.prototype.setState = function(value) {
  var states = Object.keys(this.states).map(function(key) {
     return key.toLowerCase();
  });
  if (states.indexOf(value) > -1) {
    this.state = value;
  this.elem.className = 'state-' + this.state;
};

顺便说一句,最基本形式的 setter 只是一个将属性设置为对象值的函数。你让它的具体程度取决于你硬编码到设置器中的参数数量。

function createSetter(context, prop, val) {
  switch (arguments.length) {
     case 0:
       return function(p, v) { this[p] = v; };
     case 1:
       return function(p, v) { this[p] = v; }.bind(context);
     case 2:
       return function(v) { this[prop] = v; }.bind(context);
     case 3:
       return function() { this[prop] = val; }.bind(context);
  }
}

var genericSetter = createSetter(); // any prop/val, implicit this context,
    boundSetter = createSetter({}); // any prop/val, fixed context
    propSetter = createSetter({'hello': 'world'}, 'hello') // fixed prop, any val, defined context
    propValSetter = createSetter({'hello': 'world'}, 'hello', 'dude') // fixed prop, fixed val, fixed context

【讨论】:

    【解决方案2】:

    我会选择第二个选项,因为:

    1. 避免使用我认为总是好的硬核字符串(“状态”)。
    2. 使调用的写入和读取时间更短。
    3. 如果您决定更改行为,您更愿意更改 setPending 函数还是每次设置调用?

    我认为第三点是最重要的,尽量让你的代码尽可能的可维护。

    【讨论】:

      猜你喜欢
      • 2017-10-30
      • 2012-05-16
      • 1970-01-01
      • 2020-06-09
      • 1970-01-01
      • 2015-08-17
      • 2010-11-27
      • 2011-03-05
      • 1970-01-01
      相关资源
      最近更新 更多