我应该使用哪种方法对JavaScript中的子类实例进行计数?

时间:2018-07-30 20:08:48

标签: javascript class instance counter id

我想实现一个计数器,该计数器将为类(和子类)的每个实例生成唯一的ID。

此刻我使用这个:

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"

您看到问题了吗?如果我通过首先实例化一个SubItem来做到这一点,那么每个模块都可以正常工作...但是当我首先实例化“母亲类”时,计数器就坏了。有办法解决这个问题吗?

我正在寻找的行为是:

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" 

3 个答案:

答案 0 :(得分:0)

将唯一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"

答案 1 :(得分:0)

问题是counter的{​​{1}}属性是{em> shadowing SubItem类的counter属性。因此,当以下行运行时:

Item

实例化第一个this.constructor.counter = (this.constructor.counter || 0) + 1; 时,通过原型继承,正在被访问SubItemthis.constructor.counter上的counter。但是随后,对Item的分配直接在SubItem 上分配给this.constructor.counter属性。 (因此,counter的进一步实例化将直接在SubItem而不是父类上引用counter

您可以通过SubItem来检查counter属性是否直接在构造函数上

hasOwnProperty

答案 2 :(得分:0)

我想我只会在父类和子类上都初始化计数器。我有点犹豫,但我认为它更清晰,并且简化了构造函数中的代码。这也让子类控制起点(不是我认为那很有用):

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"