【问题标题】:getter setter Maximum call stack size exceeded Errorgetter setter 超出最大调用堆栈大小错误
【发布时间】:2016-09-26 21:30:39
【问题描述】:

我正在尝试在 JavaScript 对象中学习 get 和 set

function ab(n){this.name=n;}; 
var c= new ab("abcde");  
console.log(c);
Object.defineProperty(c, 'name', {
    get: function() {
        return name;
    },
    set: function(Name) {
       this.name = Name;
        }
}); 
c.name="xyz";  
console.log(c.name); 

这里我首先使用构造函数创建对象,然后使用 get 和 set。但我收到错误“超出最大调用堆栈大小”。我没有得到这个错误的原因。感谢帮助

【问题讨论】:

    标签: javascript


    【解决方案1】:

    我想已经解释过了,setter 中的this.name = Name 再次调用了setter,这会导致无限递归。

    这个方法怎么样:

    function Ab(_name){
        Object.defineProperty(this, "name", {
            //enumerable: true, //maybe?
            get: function(){ return _name },
            set: function(value){ _name = value }
        });
    }
    
    var c = new Ab("abcde");
    console.log(c, c.name);
    

    或原型方法
    缺点:私有属性_name 是公共的

    function Ab(n){
        this.name = n;
    }
    Object.defineProperty(Ab.prototype, "name", {
        get: function(){ return this._name },
        set: function(value){ this._name = value }
    });
    

    或 ES6
    与原型方法几乎相同

    class Ab{
        constructor(n){
            this.name = n;
        }
    
        get name(){ return this._name },
        set name(value){ this._name = value }
    }
    

    【讨论】:

    • 第二种和第三种方法最适合我的情况,感谢您的回答!
    • 这 -> “导致无限递归”。确保您的吸气剂不仅仅是“返回 this.myprop”,例如"return 'MyProp: ' + this.myprop"
    【解决方案2】:

    set 语法将对象属性绑定到要在尝试设置该属性时调用的函数。

    你不需要做this.name = Name; 内部设置函数。 这递归地触发设置器导致堆栈溢出。 实际上,在这种情况下,您完全不需要二传手。仅当设置或修改属性时必须做一些额外的工作时才使用 setter。

    More

    【讨论】:

      【解决方案3】:

      您将属性 (name) 命名为与要添加属性的对象中的支持字段相同。此外,set 中的 this 运算符指的是错误的范围(具体来说,它的范围是属性,而不是对象);因此,您递归地设置 name 属性,导致堆栈溢出异常。

      您可以按如下方式修改您的代码:

      function myObject(n){ 
          this.nameValue = n;
      
          Object.defineProperty(this, 'name', {
               get: function() {
                  return this.nameValue;
              },
              set: function(value) {
                 this.nameValue = value;
              }
          }); 
      }
      
      var c = new myObject("foo");  
      console.log(c.name);       //logs "foo"
      
      c.name="bar";  
      console.log(c.name);      //logs "bar"
      

      name 属性的 getset 组件中的 this 关键字现在引用由 myObject 函数定义的对象,因为 Object.defineProperty 调用在该函数内。

      【讨论】:

      • 您只是在构造函数中创建访问器属性。甚至不需要使用 defineProperty 方法。
      【解决方案4】:

      你用错了Object.defineProperty()。在这种情况下,应该调用未初始化的Objectab

      Object.defineProperty(ab, 'name', { //.. };
      

      【讨论】:

      • 代码是对的。只是,他在setter中设置变量,再次触发setter。
      猜你喜欢
      • 2011-08-31
      • 1970-01-01
      • 2019-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-21
      • 2021-08-15
      • 2013-08-19
      相关资源
      最近更新 更多