What I'd like is the ability to wrap a JavaScript property to modify behavior on get/set.
For properties that are values, I can do the following:
var obj = {
myProperty : 0
};
function notifyOfChange(obj, propertyName) {
var propertyValue = obj[propertyName];
Object.defineProperty(obj, propertyName, {
get : function() { return propertyValue; },
set : function(newValue) {
var propertyValue = newValue;
console.log("Message from notifyOfChange.");
}
});
};
obj.myProperty = 10; // outputs "Message from notifyOfChange."
However, what if myProperty already has a getter/setter?
var obj = Object.create({}, {
myProperty : {
get : function() { return this._myProperty; },
set : function(value) {
console.log("Message from obj itself.");
this._myProperty = value;
},
configurable : true
}
});
obj.myProperty = 10; // outputs "Message from obj itself";
notifyOfChange(obj, "myProperty");
obj.myProperty = 10; // outputs "Message from notifyOfChange."
Is there a way to detect the myProperty anonymous setter so that I can call it in notifyOfChange?
Note: I'd like to make notifyOfChange work with any object, so just using a named function for the myProperty setter doesn't work.
function notifyOfPropertyChange(obj, propertyName) {
var desc = Object.getOwnPropertyDescriptor(obj, propertyName);
if ("value" in desc && desc.writable) {
// Value property
var propertyValue = obj[propertyName];
Object.defineProperty(obj, propertyName, {
get: function () { return propertyValue; },
set: function (newValue) {
propertyValue = newValue;
console.log("Message from notifyOfChange.");
},
configurable: true,
enumerable: desc.enumerable
});
} else if (desc.set) {
// Getter/setter property
// Redefine the setter, keep the getter if it exists
var originalSet = desc.set.bind(obj);
desc.set = function (newValue) {
originalSet(newValue);
console.log("Message from notifyOfChange.");
};
Object.defineProperty(obj, propertyName, desc);
}
}
You can use Object.getOwnPropertyNames to get the full list of property names to modify.
See MDN for an explanation of Object.getOwnPropertyDescriptor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With