开发者问题收集

ES6 JS 类下划线设置和获取方法返回“超出最大调用堆栈大小”

2017-09-27
436

我试图理解 JS ES6 类,我的问题是当我引用“this.”变量时,出现“超出最大调用堆栈大小”的错误。让我们看这个例子:

class Human {
  constructor(age) {
    this.age = age;
    // "this._age = age;" output:
    // Property age of instance without underscore: 34
    // Property age of instance with underscore: 34
  }

  get age() {
    return this._age;
    // Without underscore error: "Uncaught RangeError: Maximum call stack size exceeded"
  }

  set age(age) {
    this._age = age;
    // Without underscore error: "Uncaught RangeError: Maximum call stack size exceeded"
    console.log(`Without underscore: ${this.age}`);
    console.log(`With underscore: ${this._age}`);
  }
}

let john = new Human(34);
console.log(`Property age of instance without underscore: ${john.age}`);
console.log(`Property age of instance with underscore: ${john._age}`);

为什么我需要在 get 和 set 方法中使用下划线?为什么当我在构造函数中使用它时输出会这样改变?为什么当我引用实例属性时,没有使用下划线的提示?在 mdn 文档中甚至根本没有下划线。

2个回答

使用 set age 的全部意义在于,您要定义一个名为 age 的 setter。

如果您的 setter 的实现只是 this.age = <new value> ,那么您就是在 递归 调用 setter。

您不能同时拥有一个名为 age 的 setter 并尝试设置一个名为 age 的成员变量。它们必须被称为不同的名称,例如 age_age

user229044
2017-09-27

对于评论来说,这太长了。补充一下 Meagar 的(正确)答案:

set foo (val) {
  // empty
}

这是糖衣:

instance.foo = val;

因此,每次其他代码设置 foo 属性时,都会调用您的 setter。 setter 存在的原因是,万一您想做其他事情,例如运行某些验证以查看值是否有效。因此,当您拥有 setter 时,它会在您执行时被调用

instance.foo = val;

然后在 setter 中,您拥有

set foo (val) {
  this.foo = val;
}

它实际上是在调用自身。

Jared Smith
2017-09-27