替换prototype:class static getters或class fields中的值?

时间:2018-01-11 15:21:59

标签: javascript ecmascript-6 es6-class ecmascript-next

多年前,我写了自己的"声明"模仿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之类的东西被放置在"中间人"原型。 必须将此代码转换为ES6,我有两个选择: (现在不要掩盖" mixins"现在......)

选项1:静态getter(最终将作为Managers。***):

// 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:当它们着陆时的类字段(在构造时最终将作为普通对象属性):

// 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,我会得到一些非常冗长的东西,其中一个实例可以找出父级的值,而父级的父级的值是;并且,除非我为每个人创建了setter,否则我无法修改这些值

如果我使用类字段(它们甚至还不存在),我会得到更好的语法,主要的缺点是实例无法弄清楚早期的默认值是(因为所有值都在实例中)

你会做什么?

1 个答案:

答案 0 :(得分:1)

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

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

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

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

它也可以定义为静态属性,并可选择使用getter加倍,以便更容易访问类实例。

在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(...);