问题在于,在Hero 中,您将name 定义为访问器属性,但在访问器方法中,您将name 视为数据属性,这会导致无限循环。如果您查看浏览器的开发工具,您会看到堆栈溢出异常。
class Hero {
constructor(heroName) {
this.name = heroName;
}
get name() {
return this.name; // <=== Calls `get name` again, then again, then again...
}
set name(newName) {
this.name = newName; // <=== Calls `set name` again, then again, then again...
}
}
如果要将name 定义为访问器属性,则必须将其值存储在其他地方。一个流行的选择是另一个带有下划线前缀的属性,表示“在Hero 类之外的代码中保留这个”:
class Hero {
constructor(heroName) {
this._name = heroName;
// −−−−−−−−−−^
}
get name() {
return this._name;
// −−−−−−−−−−−−−−−−−^
}
set name(newName) {
this._name = newName;
// −−−−−−−−−−^
}
}
现场示例:
class Hero {
constructor(heroName) {
this._name = heroName;
}
get name() {
return this._name;
}
set name(newName) {
this._name = newName;
}
}
function getHeros() {
console.log("hi");
var hero1 = new Hero("Superman");
console.log("hi 2");
console.log(hero1.name);
document.getElementById("HerosContainer").innerHTML = "<p>" + hero1.name + "</p>";
}
<h1>
Hello World!
</h1>
<button onclick="getHeros()">
Get Heros
</button>
<div id="HerosContainer">
</div>
但如果您不需要它作为访问器属性,只需完全删除访问器方法:
class Hero {
constructor(heroName) {
this.name = heroName;
}
}
现场示例:
class Hero {
constructor(heroName) {
this.name = heroName;
}
}
function getHeros() {
console.log("hi");
var hero1 = new Hero("Superman");
console.log("hi 2");
console.log(hero1.name);
document.getElementById("HerosContainer").innerHTML = "<p>" + hero1.name + "</p>";
}
<h1>
Hello World!
</h1>
<button onclick="getHeros()">
Get Heros
</button>
<div id="HerosContainer">
</div>
暂时回到访问器:如果您有理由将name 设为访问器属性,很快您就可以通过new private fields syntax 将其保存在实例上真正私有的字段中。 (如果你通过 Babel 进行编译,你已经可以使用它了。)下面是一个适用于一些现代浏览器(包括最新的 Chrome、Chromium、Brave 和基于 Chromium 的 Edge)的示例:
class Hero {
#name; // <== Declares the field (required for private fields)
constructor(heroName) {
this.#name = heroName;
// −−−−−−−−−−^
}
get name() {
return this.#name;
// −−−−−−−−−−−−−−−−−^
}
set name(newName) {
this.#name = newName;
// −−−−−−−−−−^
}
}
现场示例:
class Hero {
#name;
constructor(heroName) {
this.#name = heroName;
}
get name() {
return this.#name;
}
set name(newName) {
this.#name = newName;
}
}
function getHeros() {
console.log("hi");
var hero1 = new Hero("Superman");
console.log("hi 2");
console.log(hero1.name);
document.getElementById("HerosContainer").innerHTML = "<p>" + hero1.name + "</p>";
}
<h1>
Hello World!
</h1>
<button onclick="getHeros()">
Get Heros
</button>
<div id="HerosContainer">
</div>