替换原型中的值:class 静态 getter 或 class 字段?

Replacing values in prototype: class static getters, or class fields?

几年前,我编写了自己的 "declare" 模仿 Dojo 的实现(有人吗?):https://github.com/mercmobily/simpleDeclare 现在已被 class 淘汰。 SimpleDeclare 的美妙之处在于我可以做到这一点:

// Basic definition of the managers store
var Managers = declare( JsonRestStores, JsonRestStores.HTTPMixin, JsonRestStores.SimpleDbLayerMixin, {

  schema: new Schema({
    name   : { type: 'string', trim: 60 },
    surname: { type: 'string', searchable: true, trim: 60 },
  }),

  storeName: 'managers',
  publicURL: '/managers/:id',

  handlePut: true,
  handlePost: true,
  handleGet: true,
  handleGetQuery: true,
  handleDelete: true,
});
var managers = new Managers();

是的,它有多重继承;是的,handePuthandlePost 等内容被放置在 "middle-man" 原型中。 必须将此代码转换为 ES6,我有两个选择: (暂时不介绍 "mixins"...)

选项 1:静态 getter(最终将成为管理器。***):

// Basic definition of the managers store
class Managers extends JsonRestStores {

  static get schema() { return new Schema({
    name   : { type: 'string', trim: 60 },
    surname: { type: 'string', searchable: true, trim: 60 },
  }),

  static get storeName() { return 'managers' }
  static get publicURL() { return '/managers/:id' }

  static get handlePut() { return true }
  static get handlePost() { return true }
  static get handleGet() { return true }
  static get handleGetQuery() { return true }
  static get handleDelete() { return true }
};
var managers = new Managers()

选项 2:class 落地时的字段(在构建时将作为普通对象属性结束):

// Basic definition of the managers store
class Managers extends JsonRestStores {

  schema = new Schema({
    name   : { type: 'string', trim: 60 },
    surname: { type: 'string', searchable: true, trim: 60 },
  })

  storeName = 'managers'
  publicURL = '/managers/:id'

  handlePut = true
  handlePost = true
  handleGet = true
  handleGetQuery = true
  handleDelete = true
};
var managers = new Managers()

问题是这些解决方案都没有原型那么好;在原型中使用这些值可以 1) 默认值 2) 实例能够找出父级的值(例如 manager.constructor.prototype)。 3) 一个实例改变这些值的能力(这有时很有用)

如果我使用 static get,我会得到一些非常冗长的东西,好处是一个实例可以计算出父项的值,以及父项的父项是;而且,除非我为每一个都创建设置器,否则我也不能修改这些值

如果我使用 class 字段(甚至还不存在),我会得到更好的语法,但 major 缺点是一个实例无法理解找出早期的默认值是什么(因为所有值都在实例中)

你会怎么做?

每次访问 属性 时,选项 1 都会创建新的 Schema 实例,这是不允许的开销,除非这是可取的行为。

选项 2 为每个 Managers 个实例创建新的 Schema 个实例。如果 Managers 被子classed 并且 schema 被覆盖,Schema 将以任何方式实例化,这会产生开销。

如果所有 Managers 个实例都应该共享相同的 schema 个实例,则应将其分配给 class 原型:

Managers.prototype.schema = new Schema(...);

它也可以定义为静态 属性 并且可以选择与 getter 一起使用,以便更轻松地访问 class 实例。

在ES.next中:

class Managers extends JsonRestStores {
  static schema = new Schema(...);

  get schema() {
    return this.constructor.schema;
  }
  ...
}

在 ES6 中:

class Managers extends JsonRestStores {      
  get schema() {
    return this.constructor.schema;
  }
  ...
}

Managers.schema = new Schema(...);