alert("Hello")
class Dog {
constructor(name, weight)
{
this.name = name;
this.weight = weight;
}
/*
get name(){
return this.name;
}
set name(value){
this.name = value;
}
*/
}
alert("Hello1");
let pies = new Dog("Reksio", 999);
alert("Hello2");
alert(pies.name);
此代码无需getter和setter即可完美运行。但是,在与它们取消注释之后,它奇怪地崩溃了:
Uncaught RangeError: Maximum call stack size exceeded
at Dog.set name [as name] ((index):44)
at Dog.set name [as name] ((index):45)
at Dog.set name [as name] ((index):45)
at Dog.set name [as name] ((index):45)
at Dog.set name [as name] ((index):45)
at Dog.set name [as name] ((index):45)
at Dog.set name [as name] ((index):45)
at Dog.set name [as name] ((index):45)
at Dog.set name [as name] ((index):45)
at Dog.set name [as name] ((index):45)
答案 0 :(得分:2)
通过让setter name
设置成员变量name
,您将一次又一次调用setter name
,直到堆栈溢出为止。
直接处理您的评论:
我认为二传手只能接听外部电话
实际上没有“内部”或“外部”呼叫的概念。我想您将“内部”定义为“从成员函数内部”或在this
是所构造对象的位置。无论哪种方式,事实并非如此。定义设置器后,无论何时尝试设置属性,无论是“内部”还是“外部”,都会调用该设置器。
您必须使用_name
之类的中间变量。否则,您将无限递归到设置name
。
class Foo {
constructor(name = "") {
this._name = name;
}
set name(newVal) {
this._name = newVal;
}
get name() {
return this._name;
}
}
const f = new Foo("foo");
console.log(f.name);
如果您想私有化内部_name
成员变量,以使API使用者必须通过name
,我很幸运使用Map
对象,该对象保持静态引用Foo
的所有实例到“私有”变量的对象。可能效率不高,但是如果隐私比性能更重要,则可以选择。