"堆栈大小超过"在创建自定义get / set时

时间:2015-07-14 23:38:10

标签: javascript setter getter

所以我有两个"名字"作为属性和作为Object.defineProperty()传递的参数。如果我选择将命名约定命名为" name"对于我的book对象以及Object.defineProperty()我收到错误调用"堆栈大小超过"在控制台上。两者之间的确切区别是什么?它是如何重要的。

var book ={
  year: 2004,
  edition : 1
};

    Object.defineProperty(book, "year",{
      get: function(){
        return this.year;
      },
      set:function(newValue){
        if(newValue > 2004){
          this.year = newValue;
          this.edition = this.edition + newValue -2004;
        }
      }
    });

    book.year = 2005;
    alert(book.edition);

谢谢

1 个答案:

答案 0 :(得分:1)

您既不能拥有属性的getter,也不能期望以相同的名称引用存储的属性。它是一个或另一个。

这会创建一个无限循环:

Object.defineProperty(book, "year",{
    get: function(){
        return this.year;
    },
...

你基本上是说当有人请求year属性时,它应该使用你的getter函数。并且,在getter函数中,你再次调用getter函数,再次调用getter函数......永远直到堆栈爆炸。此语句return this.year将简单地调用getter函数。

哦,是的,你的setter函数也有同样的问题。

如果您想要一个存储year属性值的位置,那么您必须使用不同的属性名称或使用某种闭包变量(例如私有实例值)。你不能同时拥有getter和setter以及你实际存储该值的名称的属性。它是一个或另一个。

一个简单的解决方案是只更改存储实际值的属性值的名称,然后阻止任何代码直接访问该值:

var book ={
  _year: 2004,
  edition : 1
};

    Object.defineProperty(book, "year",{
      get: function(){
        return this._year;
      },
      set:function(newValue){
        if(newValue > 2004){
          this._year = newValue;
          this.edition = this.edition + newValue -2004;
        }
      }
    });

    book.year = 2005;
    alert(book.edition);