开发者问题收集

未捕获的类型错误:无法设置第 4 行只有一个 getter 的 # 的属性 playerNo

2016-04-11
60065

我正在从使用旧的 hack JavaScript 类(函数和原型)转向使用新的 ES6 类。

我可能做了一些愚蠢的事情,但我不确定为什么不允许这样做:

class Player{
    constructor(playerNo){
        this.playerNo = playerNo;
    }    
    get playerNo(){
        return this.playerNo;
    }

    set cards(playersCards){
        this.cards = playersCards;
    }
    get cards(){
        return this.cards;
    }
}

var steve = new Player(1);

它给了我错误: Uncaught TypeError:无法设置属性 playerNo of #,该属性在第 4 行只有一个 getter

因此,我尝试了以下操作:

class Player{
    constructor(playerNo){
        this.playerNo = playerNo;
    }   
    set playerNo(no){
        this.playerNo = no;
    }
    get playerNo(){
        return this.playerNo;
    }

    set cards(playersCards){
        this.cards = playersCards;
    }
    get cards(){
        return this.cards;
    }
}

var steve = new Player(1);

这给了我: Uncaught RangeError:第 6 行超出最大调用堆栈大小 (即 this.playerNo = no; 行)。

有什么想法吗?

3个回答

设置 playerNo 时存在递归。

playerNo 设置器中,尝试设置 this._playerNo = 0

在其余代码中,继续区分设置器方法的名称和存储数据的内部属性。

Mark Stosberg
2016-04-11

您可以使用 getter 作为“受保护”属性的手段,您只能从外部读取该属性,并且它没有 setter ...

但是,在您的代码中,您试图调用一个不存在的 setter this.playerNo = playerNo ,并且在您的 getter 中,您递归地引用同一个 getter return this.playerNo ,而不是使用其中隐藏的 this._playerNo 属性(在您的构造函数中相同) - 因此出现堆栈溢出错误。

请记住,使用 getter/setter 时,您需要一些额外的存储空间来存储您的值,例如私有的 _playerNo 属性(除非您将存储委托给其他地方)。

Pete
2020-06-13

您可能想知道,但有些用例需要“ 重新定义 getter ”为“ 具有 固定 的属性”:

E.g. Instantiate a heavy object on-demand

  1. 一旦访问 getter,我们就会将其重新定义为属性和值。
  2. 下一次访问只会返回属性的值(就像缓存一样...)
let a = 10;
let b = 10;
class Player {
  get clubHistory() {
    return Object.defineProperty(this, 'clubHistory', {
      value: `clubHistory ➜ ${++b}`
    }).clubHistory;
  }

  static get team() {                            // … first ivoce Player.team …
    return Object.defineProperty(this, 'team', { // … re-defines static getter 'team' as property …
      value: `team ➜ ${--a}`                    // … e.g. new Team(..)
    }).team;                                     // … return new value (only relevant for first call)
  }
}

let player1 = new Player();
console.log('player1', player1.clubHistory); // 11 from get
console.log('player1', player1.clubHistory); // 11 from prop

let player2 = new Player();
console.log('player2', player2.clubHistory); // 12 from get
console.log('player2', player2.clubHistory); // 12 from prop

console.log(Player.team); // 9 from static get
console.log(Player.team); // 9 from static prop

console.log('player1', player1.constructor.team); // 9 from static prop
console.log('player2', player2.constructor.team); // 9 from static prop
Exodus 4D
2021-01-23