【问题标题】:Modern way to create static or Class variable for Javascript class为 Javascript 类创建静态或类变量的现代方法
【发布时间】:2016-10-25 06:08:39
【问题描述】:

我一直在寻找一个明确的答案,但大多数弹出的内容仍然与使用 function 定义类的旧(或者我应该说“传统”)方式有关。

根据this SO answer

ES2015 不支持类属性。

据我所知,将静态变量添加到类的唯一方法是:

https://jsfiddle.net/abalter/fknwx3n4/

class C {

  constructor(x) {
    console.log("in constructor " + x);
    this.x = x;
    this.add(this.x);
  }

  add(x) {
    console.log("in add " + x);
    C.alist.push(x);
  }

  show() {
    console.log("in show");
    console.log(C.alist);
  }
}

// MUST be done outside of actual class definition.
C.alist = [];

c1 = new C(5);
c1.show();
c2 = new C(10);
c1.show();
c2.show();

故事就这样结束了吗?在类定义中无法做到这一点似乎很奇怪。

【问题讨论】:

  • 是的,故事到此结束。将这些属性放在类定义之后没有任何问题,顺便说一句
  • ES7 支持类属性。但是不,这不是 ES2015 故事的结局。该数组可以在构造函数中设置为实例属性。
  • @Vohuman:ES7 不会,而且可能 ES8 也不会。
  • @Vohuman This proposal is still on stage 1。已经很久了。我不确定为什么它没有向前发展,因为看起来很多人都希望看到它。
  • @abalter:不,我的意思是只有C.alist = []; 是单例对象。当然,在一切都是类的 Java 中,你需要一个额外的类来创建单例实例,而在 JS 中直接创建对象要简单得多。

标签: javascript class oop ecmascript-6 static-members


【解决方案1】:

您可以在定义类后立即调用一个静态函数来初始化所有静态成员,然后可以选择删除该函数。 (可能重置静态变量是一项功能?)

这将允许您将所有静态变量保留在类声明中。

class C {
  static init() {
    C.alist = [];
  }

  constructor(x) {…}
  add(x) {…}
  show() {…}
}
C.init();
delete C.init;

另一种选择是在构造函数中初始化静态变量,但这需要在使用静态变量之前至少实例化一个对象。

class C {
  constructor(x) {
    C.alist = C.alist || [];
    …
  }
  add(x) {…}
  show() {…}
}

【讨论】:

  • 有趣...也有点别扭,但至少在构造函数中。
  • @abalter 我已经更新了。也许你会发现这个其他选项不那么尴尬?它还允许您稍后重新设置所有静态变量。
  • 我会编码 this.alist = [] 而不是 C.alist = []。为什么实例应该共享相同的信息?那是在滥用一个类。
  • @Vohuman 你是说它在滥用 JS 类吗?因为在 OOP 中它是完全合法且非常常见的。
  • @abalter 我肯定会把旧答案放回去。不过我更喜欢这个,因为它允许语法感觉更自然一些,并且唯一留在课堂之外的部分是一些帮助代码。我对我的其他解决方案也需要实例化一个对象有点不满意。
【解决方案2】:

如果您只关心将类及其静态属性封装在一个结构中,您应该考虑使用模块模式(就像we used it in ES5 包含构造函数和原型一样)。

在 ES6 中,您还可以使用 Object.assign

const C = Object.assign(class {
    constructor() {
        …
    }
    methods() { … }
    …
}, {
    of(x) { … },
    static_methods() {…},
    …
    static_property: …
});

【讨论】:

  • 我的心情很复杂。它可以工作,甚至允许在一定程度上分离关注点,但会丢失很多语法糖。扩展类时,我们的任何一种解决方案都会受到影响吗?
  • 不,您仍然可以毫无问题地使用extends C。您唯一丢失的语法糖是super,当您将静态方法放入对象字面量时,您必须在类主体中使用static static_method() { super…}
  • 万一有人关心,这隐约让人想起 Ember 使用的reopenClass 模式。
猜你喜欢
  • 1970-01-01
  • 2015-05-26
  • 1970-01-01
  • 2020-10-25
  • 2012-09-30
  • 1970-01-01
  • 2012-06-24
  • 2011-11-20
相关资源
最近更新 更多