【问题标题】:Can I use class variables in the parent class's static methods in ES6?我可以在 ES6 的父类的静态方法中使用类变量吗?
【发布时间】:2018-05-10 07:32:11
【问题描述】:

对不起,如果这是奇怪的或反模式。

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

class User extends Model {
  //...
    static getAll(){
      db.execute('SELECT * FROM users');
    }
}

由于我有多个模型,我可能想要一个 getAll 方法,因此在 Model 类上定义 getAll 似乎很理想,它引用了 tableName 类变量。理想情况下,它看起来像

class Model {
  static getAll(){
    db.execute(`SELECT * FROM ${this.tableName}`);
  }
}
//...
User.tableName = 'users';

这行不通,因为 ES6 不喜欢你这样定义类变量。 There are a number of workarounds,比如在父级中添加tableName参数,然后在User中应用users

class Model {
  static getAll(tableName) {
    db.execute(`SELECT * FROM ${tableName}`)
  }
}
//...
class User extends Model{
  static getAll() {
    Model.getAll('users')
  }
}

但是像这样为一个类的所有子类显式重写继承的函数似乎是可怕的反模式。我见过的其他解决方案(例如使用静态函数返回常量,或将两个类包装在一个对象中)有点丑陋,除非我必须这样做,否则我不想采用这种模式。所以我正在寻找一种易于阅读的 ES6 模式,它可以让我执行以下操作:

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

这样的解决方案是否存在,或者是否值得在 ES5 中“艰难地”这样做?

【问题讨论】:

  • this fiddle 这样的东西至少能好一点吗?
  • 它并没有解决必须在每个孩子中考虑所有父母方法的问题,这是我试图避免的主要事情。
  • 我知道,这就是为什么我把它作为评论 :p 因为我知道这不是一个答案
  • 重读您的问题,我想我在下面的回答中误解了它。从第二个角度看,听起来您想使用Model.getAll 而不是User.getAll,对吧?如果是这样的话,我想不出没有黑客的方法是可行的
  • @ChristianSantos 没错——我想使用ModelgetAll 方法,而不必在User 上重新定义它。可以肯定的是,这在 Ruby 和其他 OOPL 中是直接可行的。是否有其他方法可以在保持干燥的同时有效地做同样的事情?也许没有 ES6 类继承?

标签: javascript node.js inheritance ecmascript-6


【解决方案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());

【讨论】:

  • 嗯。这以前不起作用 - 可能是由于其他地方的错误。不过谢谢!
  • 更好地使用class User extends Model { static tableName = 'users'; }
【解决方案2】:

虽然这感觉有点骇人听闻——但有一种方法可以使用关于 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

【讨论】:

  • 这看起来是最不痛苦的做法:我不知道静态 getter,但看起来它们与适当的类变量只有一点点不同。它确实适用于我的代码,谢谢!
猜你喜欢
  • 1970-01-01
  • 2017-09-01
  • 2020-10-18
  • 2010-09-09
  • 2017-12-26
  • 1970-01-01
  • 1970-01-01
  • 2014-05-14
相关资源
最近更新 更多