getter setter超出最大调用堆栈大小错误

时间:2016-05-28 17:53:17

标签: javascript

我正在尝试学习get和设置JavaScript对象,我尝试了

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。但我收到错误"超出最大调用堆栈大小"。我没有得到这个错误的原因。谢谢你的帮助

4 个答案:

答案 0 :(得分:21)

我认为已经解释过,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 }
}

答案 1 :(得分:3)

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

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

More

答案 2 :(得分:1)

您将属性(name)命名为与您要添加属性的对象中的支持字段相同。此外,this内的set运算符指的是错误的范围(具体来说,它的范围是属性,而不是对象);因此,您以递归方式设置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"

this属性的getset组件中的name关键字现在引用myObject函数定义的对象,因为Object.defineProperty调用是在那个功能。

答案 3 :(得分:0)

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

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