JavaScript ES6类中对“ set function()”的不确定调用

时间:2019-04-16 10:19:58

标签: javascript class ecmascript-6 callstack

我正在JavaScript中运行此简单类,但在控制台中却给我一个“超出最大调用堆栈大小”的错误。和帮助?!?

class Person {

        constructor(name, age) {
            this.name = name;
            this.age = age;
        }

        get name() {
            return String(this.name);
        }
        get age() {
            return String(this.age);
        }

        set name(name) {
            this.name = name;
        }

        set age(age) {
            this.age = age;
        }
}

let p1 = new Person('Ehsan', 23);

这是控制台的屏幕截图

here is the screen shot of console}

3 个答案:

答案 0 :(得分:3)

如果要指示不直接使用age属性,则应使用与setter和getter所使用的名称不同的属性名称。如果setter / getter设置或获取的属性与setter或getter的名称相同,它将继续调用自身,从而导致错误。

一个常见的约定是在属性前加下划线:

class Person {

  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  get name() {
    return String(this._name);
  }
  get age() {
    return String(this._age);
  }

  set name(name) {
    this._name = name;
  }

  set age(age) {
    this._age = age;
  }
}

let p1 = new Person('Ehsan', 23);
console.log(p1.age);
p1.age = 32;
console.log(p1.age);

但是,消费者仍然可以通过p1._age看到该属性-如果您想防止这种情况,可以使用闭包和WeakMap将其设置为私有:

const Person = (() => {
  const privateVals = new WeakMap();
  return class Person {
    constructor(name, age) {
      const privateObj = {};
      privateObj.name = name;
      privateObj.age = age;
      privateVals.set(this, privateObj);
    }

    get name() {
      return String(privateVals.get(this).name);
    }
    get age() {
      return String(privateVals.get(this).age);
    }

    set name(name) {
      privateVals.get(this).name = name;
    }

    set age(age) {
      privateVals.get(this).age = age;
    }
  }
})();

let p1 = new Person('Ehsan', 23);
console.log(p1.age);
p1.age = 32;
console.log(p1.age);

答案 1 :(得分:2)

您不能有一个getter / setter对和一个具有相同名称的字段。设置器中的this.name =本身将称为设置器。如果您确实需要吸气剂/吸气剂,请使用其他字段,例如this._name = ...但是老实说:不要在这里使用getter / setter。如果您进行person.name = 15,则应该解决此问题,而不要尝试使用getters / setter方法来实现。

答案 2 :(得分:0)

我相信您只需要在构造函数中重命名类变量就可以了?

class Person {

  constructor(name, age) {
    this._name = name;
    this._age = age;
  }

  get name() {
    return String(this._name);
  }
  get age() {
    return String(this._age);
  }

  set name(name) {
    this._name = name;
  }

  set age(age) {
    this._age = age;
  }
}