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

时间:2017-11-27 05:37:12

标签: javascript node.js inheritance ecmascript-6

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

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

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并不像你那样定义类变量。 There are a number of workarounds,例如在父级中添加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. 不必显式引用子类中的继承方法。
  4. 这样的解决方案是否存在,或者是否值得以“艰难的方式”进行。在ES5?

2 个答案:

答案 0 :(得分:1)

  

这不起作用,因为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 :(得分:0)

虽然这感觉有些迟钝 - 有一种方法可以使用这两个关于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