以下代码将添加属性' id'到对象' obj'。调用getter和setter时会有一个console.log执行。
let obj = {}
Object.defineProperty(obj, 'id', {
set: (val) => { console.log('set'); this.id = val; },
get: () => { console.log('get'); return this.id; }
})
obj.id = 1;
// 'set'
console.log(obj.id);
// 'get'
// 1

我想为构造函数添加相同的功能,但它最终会循环。
let myObject = function(){
Object.defineProperty(this, 'id', {
set: (val) => { console.log('set'); this.id = val; },
get: () => { console.log('get'); return this.id; }
})
}
let obj = new myObject();
obj.id = 1;
// 'set'
// 'set'
// 'set'
// ...
// error
console.log(obj.id);

如何解决而不创建伪私有变量这个问题' _id'?
顺便说一下,在使用类时遇到同样的问题。
答案 0 :(得分:0)
这有点奇怪,但似乎setter开始以递归方式调用自身,因此代码进入无限循环的setter调用,然后表示超出了最大调用堆栈大小。我可以提出一个解决方案:在创建的实例上定义setter和getter。这样它也有效:
let myObject = function(){
}
let obj = new myObject();
Object.defineProperty(obj, 'id', {
set: (val) => { console.log('set'); this.id = val; },
get: () => { console.log('get'); return this.id; }
})
obj.id = 1;
console.log(obj.id);
<强> UPD:强>
您还可以创建一些工厂函数,它将自动添加id
属性实例:
function objectFactory (num) {
let myObject = function(){
};
let instance = new myObject();
Object.defineProperty(instance, 'id', {
set: (val) => { console.log('set ' + num); this.id = val; },
get: () => { console.log('get ' + num); return this.id; }
});
return instance;
}
let obj = objectFactory(1);
let obj1 = objectFactory(2);
let obj2 = objectFactory(3);
obj.id = 1;
obj1.id = 1;
obj2.id = 1;
console.log(obj.id);
console.log(obj1.id);
console.log(obj2.id);
答案 1 :(得分:0)
我想我找到了答案。只要您引用_id而不是this._id,就不会在对象本身中存储任何值。
let myObj = function(){
let _id
Object.defineProperty(this, 'id', {
get: () => {console.log('get'); return _id},
set: (val) => {console.log('set'); _id = val}
})
}
let obj = new myObj()
obj.id = 1
// -> 'set'
console.log(obj.id)
// -> 'get'
// -> 1
console.log(obj)
// -> {}
// the _id variable will not be part of the object!