Monday, March 23, 2009

[IE8] Global constants via defineProperty ... Illusion!

I do not want to spend a single word about Internet Explorer 8 Object.defineProperty implementation, which works only with DOM prototypes and the super global window but not with user defined objects, as __defineGetter__ and __defineSetter__ do since ages:
Standards are an important factor to ensure browser interoperability for the Web developer (n.d. oh, really?!??!?!!!!). The accessor property syntax has only recently begun standardization (you guys have a weird concept of the time ... or the meaning of "recent" in IT therms ...). As such, many browsers support an older, legacy syntax ... (n.d. which at least has dignity to work with every kind of object ... )

Anyway, few things are better than nothing, so welcome to Object.defineProperty!

Let IE8 behaves like every other or change every other to respect new M$ standard?

This was the first question when I thought about this new global function: does it mean we finally have a way to emulate __defineGetter__ and setter in Internet Explorer as well? First of all: NO, since IE implementation works only with DOM and window, secondly, we need to add an Object.prototype method (to be honest ... two) and we all know that Object.prototype is the "untouched one".
So, let's do in the other way, we can add a method to the global function Object, which is less obtrusive and more compatible ^_^;;

if(!Object.defineProperty && Object.prototype.__defineGetter__)
// a silly WebReflection idea
Object.defineProperty = function(obj, prop, getset){
obj.__defineGetter__(prop, getset.get);
obj.__defineSetter__(prop, getset.set);

Well done, now we should simply parse every passed obj to understand if those are IE8 compatible ... is it worthy? ... dunno yet, just for fun, destroy IE8 environment with this evil Object.prototype if you want:

if(!Object.prototype.__defineGetter__ && Object.defineProperty){
// the second silly WebReflection idea!
Object.prototype.__defineGetter__ = function(prop, get){
Object.defineProperty(this, prop, {get:get});
Object.prototype.__defineSetter__ = function(prop, set){
Object.defineProperty(this, prop, {set:set});

Same problem, we cannot use a method with every browser ... the only good part of this global Object method is described in this msdn page, an addEventListener, finally, for IE8 too and every node without usage of wrappers (usually the $ object ...)

The insane idea: Global Constants for EveryBody?

... oooOOOOOOOO Crap! Even if we can do something like this:

// create the evil plan!
return "I am like a constant!";
throw new Error(
"You cannot change a constant, don't ya know it?"

// test the evil plan! (muHaHAHAHA in the background ...)
nobodyCanChangeMe = 123;
// Error: You cannot change a constant, don't ya know it?

You will probably be (un)surprised to know that Internet Explorer 8 (tada, tada, taDAAA!!!) completely ignore the setter whenever you decide to redefine the property!!!

// above perfect evil plan code ... plu ...

Object.defineProperty(window, "nobodyCanChangeMe", {get:function(){
return "you must be joke!";
alert(nobodyCanChangeMe); // you must be joke!

As Summary

VBScript via browser supports constants since dunno how many years. I personally wrote a PHP define like functions ages ago but nothing, Microsoft decided to release IE8 without constants, which are supported almost by evey other (FireFox, Chrome, Safari, Opera -- buggy/meaningless in the latter case) so there is no way to protect our code for JsonP requestes, safe evaluations, whatever you would like to be "99%" sure nobody can change, etc etc ... so this is a thank to IE Team, they worked hard, but this is also a: was it that difficult to put more effort in the JavaScript engine, rather than scam the world with those useless page loading benchmarks?

Enjoy the new Web 2.IE8 Era!

No comments:

Post a Comment