Wednesday, February 23, 2011

...btw, getters & setters for IE 6, 7, and 8 (almost!) : Object.createStatic

Update Yes, I did it: getters and setters for IE < 9 and other browsers


Update apparently Dojo framework explored this stuff before me



Re-Update: More limitations!!!


Apparently I have said "Hooray!" too early, @_bga told me that this way is compatible with primitives only since the moment we have a property with an object or a function, this will converted into string.
So: don't return objects or functions since these will not work as expected!
Well, still something tho ... I should probably change the title with a big "almost" ...



... pretty much, the "dream comes true" features that could open hundreds of doors for current Web development status is here, but before we can understand properly the example page, we surely need a bit of introduction about the topic ...

Getters/Setters For Everybody!

Getters and Setters are beautiful, powerful, and the ideal scenario for whatever developer behind any sort of API.
Getters and Setters work perfectly in all browsers but old IE, where the version is almost 8, due possibility to use Object.defineProperty at least with DOM prototypes and some hosted object, and it goes down to all versions we know: 7, 6, ... etc

How Does It Work

"Proxying" VBScript via JScript global execScript method, it is possible to create a VBScript Class that via factory pattern assigns a private JS object into VBScript instance, passing through a runtime create JavaScript function that will act as a factory to return the private scope object passed to create the relationship ...



IE Getters and Setters

I had the same expression when I have read something like this, but I have been too lazy to even think about a better solution.
I kinda regret I have abbandoned my VBScript experiments at some point but ... you know, I am mainly dealing with mobile browsers where IE, as exclamation, meaningful word, or acronym, is basically never mentioned.

Rewind, We've Got Getters and Setters in IE!!!

At least we have the possibility to create a static object, where "static" means that we cannot set runtime properties the way we use to with whatever JavaScript object.
In few words, and at least for me for the first time, we have to deal with properly defined Classes inside a prototypal inheritance based programming language, and one of the most highly dynamic I know.

Object.createStatic

I have tried hard to respect as much as possible new ES5 Object.defineProperties definition object, but it was not possible, for cross-browser consistencies problem, to preserve the first argument as te one that suppose to be extended via definition object, so here's the signature:

Object.defineStatic(
definitionObject:JSObject
):StaticObject;

And here the same example in JS code:

var Static = Object.createStatic({
// public
value: {
get: function () {
return this._value;
},
set: function (value) {
this._value = value;
}
},
// "protected"
_value: {
writable: true,
value: 123
}
});

// will invoke the setter
Static.value = 456;
alert(Static.value); // 456

// will throw an exception
// or it won't work
Static.whatever = "no way";


Not Suitable For Prototype

Unfortunately, if we want to preserve a cross browser behavior, we should consider that the "Static" object cannot be used as a prototype definition, due its "hosted" nature, which comes from a VBScript Class, and for this reason cannot be handled as every other object.

Suitable For ...

We can use this hack to create those kind of object that would like to be:

  • secure, it is really challenging, almost impossible in IE, to redefine a property that has been defined already via definition object

  • reasonable amount, being each Singleton creation truly expensive for the already slowest browser still on the market, aka IE < 9, we cannot benefit from this approach in order to create hundreds of instances during an application lifecycle

  • any sort of API, where the main entry point is always the same object, used mainly as a namespace, and the "magic" we would like to add could have "no limits"



As Summary

This stuff has been around for almost two years, and I am the first one that never thought about it too much, or never felt so much the need to have getters and setters in IE. Now, at least from what I knew so far, you can play with future oriented code, waiting for your worst enemy to simply die thanks to the market offer.
It's your call, I am just giving a hint ;)

Once again, the source code!

8 comments:

Kris Zyp said...

BTW, this functionality (using VBScript to create IE getters and setters) has been in Dojo for a few years: http://download.dojotoolkit.org/release-1.3.0/dojo-release-1.3.0/dojox/lang/observable.js

Darktalker said...

that's awesome!! thanks for sharing this precious piece :)
Gonna try this out!

Andrea Giammarchi said...

well Kris, let's put in this way, I have explained the "magic behind", I was not aware Dojo was already there (and Dojo announced some "strict" new stuff two years after I did), and I am pretty sure this post and your code, both come from the link I have already posted ... uh wait, that's Dojo stuff:
the lettable.txt one, isn't it? ;-)

Not everybody out ther knew it, and the "observable way" is not clarifying too much, imho.

It must be told I have never investigated into this Dojo feature tho ... so, good stuff, we own you a beer!

Anonymous said...

Hey,

This is a inquiry for the webmaster/admin here at webreflection.blogspot.com.

Can I use part of the information from your post above if I provide a backlink back to this site?

Thanks,
James

Andrea Giammarchi said...

no problems James

Kris Zyp said...

Sorry, didn't mean to diminish your post. Indeed you provide a good explanation of the VBScript getter/setter stuff, whereas we merely committed some code ;).

Erik Reppen said...

I almost kind of like the idea of getters and setters being confined to returning primitives and perhaps arrays and object literals. We could still produce useful side-effects like data-alteration triggered events within the getters and setters without running into confusing syntax behavior from getters doing things like returning self-executing functions. Would this be overly restrictive?

Andrea Giammarchi said...

there's no limit, except you cannot add runtime new getters, setters, or properties