Reputation: 494
I have lots of little objects that all need to fulfill very similar tasks and I would like to use a decorator to modify those objects since this makes things a lot easier for me. Problem is, I also need to trigger stuff as soon as certain data on these objects is accessed while at the same time preventing outside access to the actual data. Therefore, I'm using a closure to store the private data and provide magical mutators for outside access. Finally, I'm also using a constructor for no specific reason.
This is a very reduced version of the object and the parts that give me headaches:
var Foo = function () {
var hiddenState;
return {
set state (s) {
// Do something that justifies using magical accessors
state = s;
},
get state () {
// Do something that justifies using magical accessors
return state;
}
}
};
var o = new Foo();
o.state = 10;
Okay, now there are some objects that should behave a different from the rest when their mutators are used. So, I thought, I'd just overwrite the mutators and that's it:
// Let's suppose I have some reason to modify the magical accessors for some objects but not for others
Object.defineProperty(o, 'state', {
get: function () {return hiddenState /*...*/},
set: function (s) {state = s /*...*/}
});
o.state; // Ouch!
This doesn't work. I get a reference error because I'm trying to access hiddenState
when it wasn't defined within the scope of the new getter/setter pair.
I suspect JS dumps the closure that was only accessible from the old mutators as soon as I pass in the new ones. Is there some way to deal with this problem?
Upvotes: 0
Views: 58
Reputation: 664548
You can access the closure that had access to hiddenState
using Object.getOwnPropertyDescriptor
. Also, if you don't need to modifiy the getter, just don't overwrite it at all, it will persist.
var oldSetter = Object.getOwnPropertyDescriptor(o, 'state').set;
Object.defineProperty(o, 'state', {
set: function (s) {
/* do something to s */
oldSetter(s);
}
});
Upvotes: 1