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

Uncaught TypeError: Cannot set property playerNo of # which has only a getter on line 4

本文关键字:属性 playerNo 4行 getter 有一个 类型 错误 设置      更新时间:2024-04-20

我正在从使用旧的(函数和原型)的破解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: Cannot set property playerNo of # which has only a getter on line 4

所以,我尝试了以下方法:

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: Maximum call stack size exceeded on line 6(这是线this.playerNo = no;)。

有什么想法吗?

您可以通过设置playerNo进行递归。

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

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

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

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

请记住,对于getters/ssetter,您需要一些额外的存储来实现您的价值,例如私有_playerNo属性(除非您将存储委派到其他地方)。

您可能会感到奇怪,但在某些用例中"重新定义getter";作为"属性,其中固定";旨在:

例如,实例化重物按需

  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