My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

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!

Wednesday, February 16, 2011

All You Need for JSONP

I have just uploaded a truly simple, still robust, function able to do generic JSONP without pretending too much magic.

The concept is simple, we pass the url, including the parameter name used to communicate the callback name, and a callback as second argument ... that's it, 202 216 bytes minified and gzipped ( many thanks @jdalton for the catch )

Here an example:

<!-- the generic HTML page -->
<script src="JSONP.js"></script>
<script>
this.onload = function () {
var many = 0;
JSONP("test.php?callback", function (a, b, c) {
this.document.body.innerHTML += [
a, b, ++many, c
].join(" ") + "<br />";
});
JSONP("test.php?callback", function (a, b, c) {
this.document.body.innerHTML += [
a, b, ++many, c
].join(" ") + "<br />";
});
};
</script>

And here the testable demo result that should work with every bloody damned browser.

What's on the server? Nothing more than this:

<?php
if (isset($_GET['callback'])) {
header('Content-Type: application/javascript');
exit($_GET['callback'].'.call(window, "Hello", "JSONP", "!!!")');
}
?>


Enjoy ;)