Found myself in a situation in which I needed to set getters/setters for an instance's properties. Using JS, the technique I inherited was as follows:
HTMLCanvasElement.prototype.__defineGetter__("bitmapData", function() {
if(!this._bitmapData) {
this._bitmapData = new BitmapData(this.width, this.height, false, 0, this);
}
return this._bitmapData;
});
Unfortunately, although Internet Explorer 9 is light-years ahead of it's predecessors, it doesn't support this method. But after looking into it, there's a reason it doesn't; it actually supports a much cleaner API for dynamic getters and setters. This can be seen as follows:
Object.defineProperty(obj, 'property', {
get: function() {
return 'value';
},
set: function(value) {
// set-logic
}
});
The above code will operate on the obj-object, dynamically changing the
'property'-property.
So for example.
clear();
var obj = {name: 'Oliver'};
console.log(obj.name);
Object.defineProperty(obj, 'name', {
get: function() {
return 'Nassar';
}
});
console.log(obj.name);
The above code will log, in-order, the strings 'Oliver' and 'Nassar'. An issue I ran into was setting the getters and setters for a property independently. For example:
clear();
var obj = {name: 'Oliver'};
Object.defineProperty(obj, 'name', {
get: function() {
return 'Nassar';
}
});
Object.defineProperty(obj, 'name', {
set: function(value) {
// set-logic
}
});
This isn't allowed, and IE9 will throw an error. Something like 'cannot redefine defineProperty'. You need to set the dynamic-properties of the object in one-call as follows:
clear();
var obj = {name: 'Oliver'};
Object.defineProperty(obj, 'name', {
get: function() {
return 'Nassar';
},
set: function(value) {
// set-logic
}
});
For the exact signature of this method, check out: defineProperty - MDC Docs
Finally, to pass this getter/setter onto an instantiable-class, I used the following syntax:
Object.defineProperty(klass.prototype, 'property', {
get: function() {
// get-logic
}
});
I tested the above on Firefox 4+, Chrome 11+ and IE9. I don't know how far back it goes, but it's good on those modern-browsers.
Hope this helps :)