可以使用Object.defineProperty
覆盖特定属性的JavaScript getter和setter。有没有办法访问默认的getter / setter(即如果getter / setter没有被覆盖则使用的函数)?在我的自定义setter中,我想在某些情况下进行特殊处理,但在其他情况下使用默认处理。我试过了:
Object.defineProperty(obj, 'foo',
'set': function(val) {
if (useCustom) {
doCustomProcessing(obj, 'foo', val);
}
else {
obj['foo'] = val;
}
}
);
不幸的是,这会导致堆栈溢出,因为obj['foo'] = val;
会导致调用自定义setter。因此,我想找到一种方法来使用默认设置器设置foo
obj
属性。这可能吗?
答案 0 :(得分:5)
据我所知,属性要么具有值(数据属性),要么具有getter / setter(访问属性):它不能同时拥有它们。在闭包或其他属性下使用局部变量作为定义了getter / setter的属性的底层存储。
例如,
(function() {
var value;
Object.defineProperty(obj, 'foo', {
set: function(val) {
if (useCustom) {
value = doCustomProcessing(obj, 'foo', val);
} else {
value = val;
}
},
get: function() { return value; }
});
})();
答案 1 :(得分:3)
在ES6中,您可以使用Proxy object:
var myObject = {};
var myProxyObject = new Proxy(myObject, {
set: function(ob, prop, value) {
if (prop === 'counter' && value === 10) {
// Some specialised behaviour
ob.counter = 0;
}
else {
// Default setter behaviour.
ob[prop] = value;
}
// Return true otherwise you will get a TypeError in strict mode.
return true;
}
});
>>> myProxyObject.counter = 5;
>>> console.log(myProxyObject.counter);
5
>>> myProxyObject.counter = 10;
>>> console.log(myProxyObject.counter);
0
答案 2 :(得分:1)
我知道如何做到这一点的唯一方法是使变量非私有,但两个例子,第二个更简洁:
waveWriter
据我所知:
你不能引用与你在set:function(value)中使用的名称相同的值,或者最终得到一个无限循环,其中设置值调用设置值并调用自身再一次,等等。因此,你的问题。
如果您尝试将变量_foo设为private,则setter不起作用。使用这种语法,您似乎可以隐藏变量,但您无法将其隐藏起来。
答案 3 :(得分:0)
您可以执行以下操作:
const counter = new class {
count = 1;
toString () {
return this.count++;
}
}()
console.log(`${counter}`')
const myString = new class {
toString () {
return 'This is my string';
}
}();
console.log(`${myString}`);