неопределенный вызов "set function ()" в классе JavaScript ES6 - PullRequest
1 голос
/ 16 апреля 2019

Я запускаю этот простой класс в 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}

Ответы [ 2 ]

3 голосов
/ 16 апреля 2019

Если вы хотите указать, что свойство age не должно использоваться напрямую, вам следует использовать имя свойства, отличное от имени, используемого установщиками и получателями. Если свойство, которое устанавливает или получает установщик / получатель, имеет то же имя, что и установщик или получатель, оно просто будет продолжать вызывать себя, что приведет к вашей ошибке.

Общепринятое правило - ставить подчеркивание перед свойством:

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);
2 голосов
/ 16 апреля 2019

Вы не можете иметь пару геттер / сеттер и поле с тем же именем. this.name = внутри установщика сам вызовет установщик. Если вам действительно нужен метод получения / установки, используйте другое поле, например, this._name = ... Но, если честно: не используйте здесь геттер / сеттер. Если вы делаете person.name = 15, вам лучше это исправить, чем пытаться делать это с помощью методов получения / установки.

...