我不确定为什么这段代码会给我一个错误。我想要做的就是创建一个具有数组作为属性的对象。我想用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;
答案 0 :(得分:4)
你从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ánTamási在his answer中所做的事:在同一个对象上使用另一个属性。他的回答在底层属性上使用_
前缀(例如,_array
),这是JavaScript中的一个非常常见约定,“单独留下它,它是'私有'”即使没有私人财产。事实上,即使在具有真正私有属性的语言(如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));
答案 1 :(得分:2)
在编写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;
答案 2 :(得分:0)
你曾提到你想使用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);