Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有getter和setter的JavaScript类导致RangeError:超过最大调用堆栈大小_Javascript_Node.js_Node Mysql - Fatal编程技术网

带有getter和setter的JavaScript类导致RangeError:超过最大调用堆栈大小

带有getter和setter的JavaScript类导致RangeError:超过最大调用堆栈大小,javascript,node.js,node-mysql,Javascript,Node.js,Node Mysql,我目前正在试验ECMA6类。 我当前的课程如下所示 class Player { constructor(id) { this.id = id; this.cash = 350; } get cash() { return this.cash; } set cash(value) { // line 19 this.cash = value; // line 20 } }; 当我现在通过调用let playerObject=new P

我目前正在试验ECMA6类。 我当前的课程如下所示

class Player {
  constructor(id) {
    this.id = id;
    this.cash = 350;
  }

  get cash() {
    return this.cash;
  }

  set cash(value) { // line 19
    this.cash = value; // line 20
  }
};
当我现在通过调用
let playerObject=new Player(1)创建一个新对象时我收到以下错误

...\node_modules\mysql\lib\protocol\Parser.js:82
        throw err;
              ^
RangeError: Maximum call stack size exceeded
    at Player.cash (player.js:19:11)
    at Player.cash (player.js:20:15)
    at Player.cash (player.js:20:15)
    at Player.cash (player.js:20:15)
    at Player.cash (player.js:20:15)
    at Player.cash (player.js:20:15)
    at Player.cash (player.js:20:15)
    at Player.cash (player.js:20:15)
    at Player.cash (player.js:20:15)
    at Player.cash (player.js:20:15)
Press enter to exit
这与mysql库有什么关系?为什么错误会在同一行中多次出现?我只叫它一次。

你的“现金”设定者叫“现金”设定者,它叫“现金”设定者,它叫“现金”设定者


在setter中使用自己的名称访问属性setter会创建一个无限递归函数调用。

cash表示getter/setter,而cash是“private”属性

  set cash(value) { // line 19
      this._cash = value; // line 20
  }

请看一个清晰的示例。

您正在递归调用getter

它遵循一种可能的替代方案:

class Player {
    constructor(id) {
        this.id = id;
        this._cash = 350;
    }

    get cash() {
        return this._cash;
    }

    set cash(value) {
        this._cash = value;
    }
};
另一个使用
对象。定义属性

class Player {
    constructor(id) {
        this.id = id;

        var _cash = 350;
        Object.defineProperty(this, 'cash', {
            get: function() {
                return _cash;
            }

            set: function(v) {
                _cash = v;
            }
        });
    }
};
Get&setes6类为上的getter和setter带来了一种新语法 对象属性。Get和set允许我们在读卡器上运行代码 书写财产。ES5也有接球手和二传手,但不是 由于旧的IE浏览器而被广泛使用。ES5的能手和二传手做到了 没有ES6带给我们的那么好的语法。因此,让我们创建一个get 并设置为我们的名称属性

  set cash(value) { // line 19
      this._cash = value; // line 20
  }
资料来源:

示例

// ES6 get and set
class Person {
    constructor(name) {
        this._name = name;
    }

    get name() {
        return this._name.toUpperCase();
    }

    set name(newName) {
        this._name = newName;   // validation could be checked here such as only allowing non numerical values
    }

    walk() {
        console.log(this._name + ' is walking.');
    }
}

let bob = new Person('Bob');
console.log(bob.name);  // Outputs 'BOB'

我知道我迟到了,但我想我可以在这里澄清一两点:

首先是隐私问题,这是JavaScript社区长期讨论的问题

class Player {
   constructor(id) {
      this.cash = 350; // this._cash, alternatively
   }

   get cash() {
      return this.cash;
   }

   set cash(value) {
      this.cash = value;
   }
};

let player1 = new Player();
在本例中,this.cash是一个公共属性,因此您实际上不需要getter和setter方法来处理它,因为您可以使用player1.cash获取它,并使用player1.cash=newCash进行设置;它抛出错误是因为getter和setter被递归调用,正如其他人提到的

但是,如果您只是将该属性重命名为this.\u cash,则必须了解该不是私有属性。如果您尝试访问player1.\u cash,您将以与player1.cash相同的方式访问属性值

那么,我们如何实现隐私权呢?

使用ES6/ES2015有两种主要方法:使用新的基本类型或使用。我不会详细介绍该语言的这两个新特性,但我将展示在本例中如何实现这一点

使用符号: 使用弱贴图 重要的
虽然符号的语法更好,但它需要浏览器的本机支持才能实际工作。您可以使用transpiler编写它,但在后台,它将模仿旧的ES5标准。对WeakMaps的本机支持更好,另一方面,此功能只与GC和对象属性的可枚举选项配合使用。因此,最终,这是您的选择。

我对ECMA6类了解不够,但您似乎在递归调用setter。递归调用意味着什么?它意味着它在调用自己。尝试将setter方法重命名为cash以外的其他方法。重命名“内部”变量可能重复。我把
this.cash
改为
this.playerCash
。谢谢大家。@Cludch没问题。你应该养成不重复使用名称的习惯,或者如果你真的想使用这个名称,在前面加上“get”或“set”,例如“getCash”或“setCash”。真的很烦人。如果我这样做,当我想序列化/反序列化对象时会发生什么?我相信它会被序列化为
“{u-cash:350}”
,这对于通过网络发送并不理想。您必须编写一个自定义的
toString()
函数来处理此问题。
let map =  new WeakMap();

class Player {

   constructor () {
      map.set(this, {
         cash: 350
      });    
   }

   get cash(){
      return map.get(this).cash;
   }

   set cash(cash) {
      map.get(this).cash = cash;
   }

}