【发布时间】:2017-10-20 19:56:00
【问题描述】:
我正在尝试找出替代方法来将静态(或类)属性设置为 ES6 类,然后在创建类的新实例后更改它。
例如,假设我有一个名为Geo 的类,我需要一个名为all 的静态属性,它将为我提供Geo 类的所有实例的数组。
此版本有效:
class Geo {
constructor(name){
this.name = name;
Geo.all.push(this);
}
}
Geo.all = [];
ruby = new Geo("Ruby");
rocks = new Geo("Rocks");
console.log(Geo.all.length); // => 2
我宁愿不要在类定义之外设置属性。我已经尝试了一些东西,但似乎无法在类中创建可以从构造函数更新的静态属性。
我还应该提到我需要能够在不使用 Babel 或类似工具的情况下在浏览器 (Chrome) 中执行此操作。
以下是我尝试过的一些示例:
class Geo {
constructor(name){
this.name = name;
Geo.all.push(this);
}
static get all() {
return [];
}
}
ruby = new Geo("Ruby");
rocks = new Geo("Rocks");
console.log(Geo.all.length); // => 0
还有一个
class Geo {
constructor(name){
this.name = name;
Geo.all.push(this);
}
static all = [];
}
ruby = new Geo("Ruby");
rocks = new Geo("Rocks");
console.log(Geo.all.length); // => error unexpected "="
【问题讨论】:
-
在 ES6 中没有其他方法可以做到这一点。
-
Geo.all = []有什么问题? -
你不应该有一个全局的实例集合——这会导致内存泄漏和模块化(例如可测试性)问题
-
您可以在构造函数中执行
Geo.all = (Geo.all || []).concat(this);。然而,类定义之外的静态初始化程序是解决此问题的“惯用”标准方法。它还保证Geo.all的存在,甚至在创建第一个实例之前。 -
如果您想跟踪特定对象的所有实例,那么您可能不想将它们放入数组中,因为这可能会导致内存泄漏,因为这样做会迫使您的代码管理每个对象的内存(您必须手动将其从数组中删除,以便垃圾收集器释放它,这会扼杀垃圾收集的很多用处)。您可以将它们放在
weakMap或weakSet中,具体取决于您希望如何访问它们并且不会杀死垃圾收集。
标签: javascript class oop object ecmascript-6