Javascript 访问器属性混乱

Javascript Accessor properties confusion

我不确定为什么这段代码会给我一个错误。我想要做的就是创建一个对象,该对象的数组为 属性。我想用 setter 和 getter 来实现这一点,但是由于某种原因,当我在 setArray 函数中执行 this.array = [] 时,我得到 超出最大调用堆栈大小.我究竟做错了什么 ?关于 Javascript 的访问器属性,我缺少什么。

var obj = {
  set array(size) {
   this.array = [];
   for (var i = 0; i < size; i++){
        this.array[i] = i; 
   }
  }
};


var myObj = Object.create(obj); 
myObj.array = 20; 

当您编写 this.array = [] 时,您正在使用 setter 本身内部的 setter。介绍另一名成员,例如 _array 并将其填写在 array 属性.

的 setter 中
var obj = {
  _array: [],
  set array(size) {
   for (var i = 0; i < size; i++){
      this._array[i] = i; 
   }
  }
};


var myObj = Object.create(obj); 
myObj.array = 20; 

您正在从 setter 中分配给带有 setter 的 属性,这就是它永远递归的原因:

var obj = {
    set array(size) {                   // <== The property is called `array`
        this.array = [];                // <== This calls the setter
        for (var i = 0; i < size; i++){
            this.array[i] = i;          // <== This would fail because there's no getter
        }
    }
};

您必须将值存储在其他地方,例如我们在这里创建一个私有范围并关闭一个变量:

var obj = (function() {
    var array = [];
    return {
        set array(size) {
            array = [];                // No `this` here
            for (var i = 0; i < size; i++) {
                array[i] = i;          // No `this` here
            }
        },
        showArray() {
            console.log(array);
        }
    };
})();
  
var myObj = Object.create(obj); 
myObj.array = 20; 
myObj.showArray();

你问的是关于回避这个功能。您需要使 属性 的值真正私有的函数。但是,如果您出于某种原因不想使用它,并且您对它的真正私密性并不那么在意,您可以像 Zoltán Tamási 在 中所做的那样:在 属性 上使用另一个 属性同一个对象。他的回答在基础 属性 上使用了 _ 前缀(例如 _array),这是 非常 中的常见约定 Java "leave this alone, it's 'private'" 的脚本,即使没有私有属性。事实上,即使在具有真正私有属性的语言中(如 Java,它们被称为实例字段),通常也有某种形式的强大反射机制可以用来绕过它,所以...

如果您这样做,需要考虑的一件事是您是否希望在序列化时将私有 属性 包含在 JSON 中。如果没有,也只需实现 toJSON,这样您就可以控制在序列化过程中包含哪些属性:

var obj = {
    _array: [],
    foo: "a value to include in JSON",
    set array(size) {
        this._array = [];          // Note the _
        for (var i = 0; i < size; i++) {
            this._array[i] = i;
        }
    },
    showArray() {
        console.log(this._array);
    },
    toJSON() {
        return {
            // Here we list only the properties we want to have
            // included in the JSON
            foo: this.foo
        };
    }
};
  
var myObj = Object.create(obj); 
myObj.array = 20; 
myObj.showArray();
console.log(JSON.stringify(myObj));

您曾提到您想要使用 setter 和 getter,此代码段仅使用 obj.array 而不是 showArray 来查看对象的数组。

var obj = (function() {
    var _array = [];
    return {
        get array(){
            return _array;
        },
        set array(size) {
            _array = [];              
            for (var i = 0; i < size; i++) {
                _array[i] = i;       
            }
        }
    };
})();

obj = Object.create(obj);
obj.array = 20;
console.log(obj.array);