类中的获取器和设置器的无限循环

时间:2018-07-16 14:47:28

标签: javascript ecmascript-6

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)
  1. 为什么我不能单独使用吸气剂?
  2. 为什么在添加简单的getter和setter之后好像发生无限递归一样崩溃?
  3. 如何修复getter和setter?

1 个答案:

答案 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的所有实例到“私有”变量的对象。可能效率不高,但是如果隐私比性能更重要,则可以选择。