I was further convinced this week that the world needs JASPA when my Flash developer colleague asked me about closures in JavaScript. He’s been knee-deep in AS3 for almost a year, so JavaScript must seem rather weak now.
Unlike JavaScript and AS2, AS3 supports method closures implicitly; so I made sure they were built into the JAS language. Such a thing is not native to JavaScript so the JASPA compiler automatically generates a call to helper function jaspa.closure
whenever an object’s method is referenced.
If you’ve ever used Delegate.create
in AS2, then you’ve encountered this issue. If you don’t see the problem, consider this example in JavaScript:
- var Cat = function(){
- this.voice = ‘Miaow’;
- }
- Cat.prototype.speak = function(){
- alert( this.voice );
- }
- var Sammy = new Cat;
- Sammy.speak(); // alerts “Miaow”
- var Callback = Sammy.speak;
- Callback(); // alerts undefined
As soon as we’ve created a reference to the function member, we’ve severed it from its owner, so when we call it, it’s not being called on the object. In JavaScript and AS2 we need to use a method like Delegate.create
to explicitly create a closure. Here’s an example:
- function makeClosure( obj, func ){
- var closure = function(){
- return func.apply( obj, arguments );
- }
- closure.apply = function( obj, args ){
- return func.apply( obj, args );
- }
- closure.call = function( obj ){
- var args = [];
- for( var i = 1; i < arguments.length; i++ ){
- args.push( arguments[i] );
- }
- return func.apply( obj, args );
- }
- return closure;
- }
It’s basically a wrapper function which seals in the original arguments. Additionally apply
and call
must be overridden or calling them directly will spoil the party. Try it with the Cat example and you’ll see the desired result.
- var Callback = makeClosure( Sammy, Sammy.speak );
- Callback(); // alerts “Miaow”