ES6中可以在父类的静态方法中使用类变量吗?

问题描述 投票:0回答:3

抱歉,如果这很奇怪或反模式。

假设我在子类上有一个静态方法,例如(为了可读性而大大简化)

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 模式,它可以让我执行以下操作:

  1. 从父类继承静态方法。
  2. 引用父类中的类变量(或等效的东西),以便可以为不同的子类指定它们
  3. 不必在子类中显式引用继承的方法。

这样的解决方案是否存在,或者是否值得在 ES5 中以“困难的方式”来实现?

javascript node.js inheritance ecmascript-6
3个回答
2
投票

这是行不通的,因为 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());


1
投票

虽然这感觉有点 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


0
投票

@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

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.