抱歉,如果这很奇怪或反模式。
假设我在子类上有一个静态方法,例如(为了可读性而大大简化)
class User extends Model {
//...
static getAll(){
db.execute('SELECT * FROM users');
}
}
由于我有多个模型,我可能需要一个
getAll
方法,因此在 getAll
类上定义 Model
似乎是理想的选择,它引用了 tableName
类变量。理想情况下它看起来像这样
class Model {
static getAll(){
db.execute(`SELECT * FROM ${this.tableName}`);
}
}
//...
User.tableName = 'users';
这是行不通的,因为 ES6 不喜欢你这样定义类变量。 有很多解决方法,例如在父级中添加
tableName
参数,然后在 users
中对其应用 User
:
class Model {
static getAll(tableName) {
db.execute(`SELECT * FROM ${tableName}`)
}
}
//...
class User extends Model{
static getAll() {
Model.getAll('users')
}
}
但是像这样显式地为类的所有子代重写继承的函数似乎是可怕的反模式。我见过的其他解决方案(例如使用静态函数返回常量,或者将两个类包装在一个对象中)有点丑陋,除非必须,否则不是我想要承诺的模式。所以我正在寻找一种易于阅读的 ES6 模式,它可以让我执行以下操作:
这样的解决方案是否存在,或者是否值得在 ES5 中以“困难的方式”来实现?
这是行不通的,因为 ES6 不喜欢你这样定义类变量。
是什么让你这么想?
User
是一个与其他函数类似的函数。静态方法成为该函数的属性。将属性直接分配给 User
效果很好。
class Model {
static getAll() {
return `SELECT * FROM ${this.tableName}`;
}
}
class User extends Model {}
User.tableName = 'users';
class Product extends Model {}
Product.tableName = 'product';
console.log(User.getAll());
console.log(Product.getAll());
虽然这感觉有点 hackish —— 有一种方法可以使用关于 ES6 类的这两个事实来实现你所需要的:
static get
来定义静态 getter ——这些 getter 将充当静态属性。 this
来调用其他静态方法。这意味着父类的静态方法可以使用 this
来引用子类中的静态方法。 总而言之,代码将如下所示:
class Model {
static getAll() {
console.log(this.tableName); // will refer to child's static getter
}
static randomFunc() {
console.log(this.tableName); // will also refer to child's static getter
}
}
class User extends Model {
static get tableName() {
return "users"; // define child's tableName here
}
}
class Worker extends Model {
static get tableName() {
return "workers"; // define child's tableName here
}
}
User.getAll(); // prints users
User.randomFunc(); // prints users
Worker.getAll(); // prints workers
Worker.randomFunc(); // prints workers
@Christian Santos 好的解决方案的简化
class Model {
static getAll() {
console.log(this.tableName); // will refer to child's static var
}
static randomFunc() {
console.log(this.tableName); // will also refer to child's static var
}
}
class User extends Model {
static tableName = "users";
}
class Worker extends Model {
static tableName = "workers";
}
User.getAll(); // prints users
User.randomFunc(); // prints users
Worker.getAll(); // prints workers
Worker.randomFunc(); // prints workers