简体   繁体   English

我应该使用什么方法来计算 JavaScript 中子类的实例?

[英]What method should I use to count instances of subclasses in JavaScript?

I would like to implement a counter that will generate a unique ID for every instances of classes (and subclasses).我想实现一个计数器,它将为类(和子类)的每个实例生成一个唯一的 ID。

At the moment I use this:目前我使用这个:

 class Item { constructor(type) { this.constructor.counter = (this.constructor.counter || 0) + 1; this.type = type || "item"; this._id = this.type + "_" + this.constructor.counter; console.log(this.id); } get id() { return this._id; } } class SubItem extends Item { constructor() { super("sub_item"); } } var test1 = new Item(); // <- "item_1" var test2 = new Item(); // <- "item_2" var test3 = new Item(); // <- "item_3" var test4 = new Item(); // <- "item_4" var test5 = new SubItem(); // <- "sub_item_5" var test6 = new SubItem(); // <- "sub_item_6" var test7 = new Item(); // <- "item_5" var test8 = new Item(); // <- "item_6"

Do you see the problem?你看到问题了吗? If I do it by instantiating a SubItem first, every is working correctly... But when I instantiate the "mother class" first, the counter is broken.如果我先实例化一个子项,每个都正常工作......但是当我首先实例化“母类”时,计数器坏了。 Is there a way to solve this problem?有没有办法解决这个问题?

The behavior I am looking for is:我正在寻找的行为是:

var test1 = new Item(); // <- "item_1" 
var test2 = new Item(); // <- "item_2" 
var test3 = new Item(); // <- "item_3" 
var test4 = new Item(); // <- "item_4" 
var test5 = new SubItem(); // <- "sub_item_1" 
var test6 = new SubItem(); // <- "sub_item_2" 
var test7 = new Item(); // <- "item_5" 
var test8 = new Item(); // <- "item_6" 

The problem is that the counter property on the SubItem is shadowing the counter property on the Item class.问题是,在counter上的财产SubItem遮蔽counter对房地产Item类。 So, when the following line runs:因此,当以下行运行时:

this.constructor.counter = (this.constructor.counter || 0) + 1;

When the first SubItem is instantiated, the this.constructor.counter that is being accessed is the counter on Item , via prototypal inheritence.当第一个SubItem被实例化时,正在访问this.constructor.counterItem上的counter ,通过原型继承。 But then the assignment to this.constructor.counter assigns to the counter property directly on the SubItem .但是随后对this.constructor.counter分配直接分配给SubItem 上的counter属性。 (so, further instantiations of SubItem will refer to the counter directly on SubItem rather than the parent class). (因此,进一步的实例SubItem将指counter直接在SubItem ,而不是父类)。

You might check to see if the counter property is directly on the constructor instead, via hasOwnProperty :您可以通过hasOwnProperty检查counter属性是否直接在构造函数上:

 class Item { constructor(type) { this.constructor.counter = ((this.constructor.hasOwnProperty('counter') && this.constructor.counter) || 0) + 1; this.type = type || "item"; this._id = this.type + "_" + this.constructor.counter; console.log(this.id); } get id() { return this._id; } } class SubItem extends Item { constructor() { super("sub_item"); } } var test1 = new Item(); // <- "item_1" var test2 = new Item(); // <- "item_2" var test3 = new Item(); // <- "item_3" var test4 = new Item(); // <- "item_4" var test5 = new SubItem(); // <- "sub_item_5" var test6 = new SubItem(); // <- "sub_item_6" var test7 = new Item(); // <- "item_5" var test8 = new Item(); // <- "item_6"

I think I would simply initialize the counter on both the parent and the subclass.我想我会简单地在父类和子类上初始化计数器。 I'm kind of on the fence, but I think it's clearer and simplifies the code in the constructor.我有点犹豫,但我认为它更清晰并简化了构造函数中的代码。 This also lets the subclass control the starting point (not that I think that's super useful):这也让子类控制起点(不是我认为这非常有用):

 class Item { constructor(type) { this.constructor.counter++; this.type = type || "item"; this._id = this.type + "_" + this.constructor.counter; console.log(this.id); } get id() { return this._id; } } Item.counter = 0 // initialize class SubItem extends Item { constructor() { super("sub_item"); } } SubItem.counter = 0 // initialize var test1 = new Item(); // <- "item_1" var test2 = new Item(); // <- "item_2" var test3 = new Item(); // <- "item_3" var test4 = new Item(); // <- "item_4" var test5 = new SubItem(); // <- "sub_item_5" var test6 = new SubItem(); // <- "sub_item_6" var test7 = new Item(); // <- "item_5" var test8 = new Item(); // <- "item_6"

Put the unique ID outside the constructor and allow it to be scoped by all classes that will increment it.将唯一 ID 放在构造函数之外,并允许它由将增加它的所有类限定。

 let INSTANCE_COUNT = 0; class Item { constructor(type) { this.type = type || "item"; this._id = `${this.type}_${INSTANCE_COUNT++}`; console.log(this.id); } get id() { return this._id; } } class SubItem extends Item { constructor() { super("sub_item"); } } var test1 = new Item(); // <- "item_0" var test2 = new Item(); // <- "item_1" var test3 = new Item(); // <- "item_2" var test4 = new Item(); // <- "item_3" var test5 = new SubItem(); // <- "sub_item_4" var test6 = new SubItem(); // <- "sub_item_5" var test7 = new Item(); // <- "item_6" var test8 = new Item(); // <- "item_7"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM