替换原型中的值:类静态获取器,还是类字段?



几年前,我编写了自己的"声明"实现,模仿Dojo的(任何人?): https://github.com/mercmobily/simpleDeclare 这现在已经被class淘汰了。SimpleDeclaration的美妙之处在于我可以这样做:

// 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(最终将成为经理。

// 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 在每次访问属性时创建新的Schema实例,这是不允许的开销,除非这是可取的行为。

选项 2 为每个Managers实例创建新的Schema实例。如果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(...);

最新更新