NetBen Ramblings about JavaScript and frontend development.

19Nov/10Off

Code on demand

Ever inserted JavaScript libraries in the wrong order? Annoying isn't it? Next to being a little bit irritating, it also prevents some possibilities like async loading. This can be fixed by simply writing your code to be "on demand" friendly. The concept is so blatantly obvious and at first you will scratch your head at the given examples thinking "what's he on about", but you'd be amazed how often people simply don't do it.

A JavaScript goes through two stages when loaded:

  1. evaluation
  2. interpretation/execution

Evaluation can be considered compilation, it simply translates JavaScript to something the browser can run. Interpretation is a runtime stage where code is actually executed where it needs to be executed. Consider the following two .js files

// file: x.js
var x = {
   message : "Hello world"
};
// file: y.js
var y = x.message;
function shout(){
   alert( y );
};

If y.js is loaded before x.js, there will be an "Object not found" or "undefined doesn't have property message" exception, the order of your files are significant and other then refactoring, the only option you have is to simply put the files in the right order. Furthermore when using a dynamic script loader such as RequireJS, you will have to do some extra work to shoehorn your files in the right order still.

The solution is "on demand" coding.

// file: x.js
var x = {
   message : "Hello world"
};
// file: y.js
var y;
function shout(){
   y || ( y = x.message );
   alert( y );
};

What has changed other then having more code? First, the y variable is set when you need it rather then when y.js file is loaded and interpreted. There's still an order issue but it's less painful and best of all, your scripts are now compatible with RequireJS without the need of extra work to maintain interpretation order.

Consider the following RequireJS usage:

require( [ "y.js" , "x.js" ] , function(){
   shout();
});

This will/can break with the first example since y.js can be interpreted before x.js. However with the "on demand" example, the order became meaningless, so it will work just fine with minimum effort.

Consider another circumstance:

<script src="y.js"></script>
<script src="x.js"></script>
<script>
   window.onload = function () {
      shout();
   }
</script>


This will most certainly break with the first example ( "Object not found" exception ), but again, it will work perfectly fine with the "on demand" example. A little change and your code becomes a heck more robust.

Now why is this important to write about? Well firstly a lot of JavaScript libraries are written with dependency resolving at interpretation time. jQuery and plugins using other plugins springs to mind, even jQueryUI does this when you use an exploded (not concatenated) version. If you ever plan to start using a dynamic script loader, this will simply give you headaches, whereas if they where all written in the "on demand" way, it would be compatible right from the get go.

I seriously hope people will read this, understand the concept and write more robust scripts/plugins/widgets and whatnot. It will create a lot nicer mashup environment up until everyone writes their code the define() way.

Filed under: JavaScript 2 Comments
31Mar/10Off

Internet Explorer is in trouble

Over a decade ago, I found myself baffled at the fact that the roles where reversed. It suddenly became more enjoyable to develop for Internet Explorer (5) then for Netscape Navigator. What the hell happened? IE gained momentum and next to aggresive warfare with Netscape, Microsoft pionered a rather spiffy browser which became a defacto standard for modern day browsers. Netscape became insignificant as a development target, you developed for IE or bust. The innovation ended with IE6 in 2001 and all was well.

IE6 was good and innovation for the holy trinity (JS/CSS/HTML) remained perceivably stagnant for 5 years. The craving for innovation however was still there and during those 5 years Flash filled that niche providing standards for rich media.

Then came Firefox

Whilst Firefox 1.0 was launched in 2004, it became mainstream and thus meaningful (in my opinion) in 2006 with FF2 approximatly 1 year after Jesse James Garret coined the term Ajax based on the endeavours from a spiffy search engine company and obviously the work at Adaptive Path. From then on JavaScript became more interresting and caused a boom in rich interaction development, developers realised that in theory, what Flash offered could also be done with just the holy trinity. Well.. some things needed to change first.

Webstandards

WHATWG pionered HTML5 back in 2004, which W3C adapted in 2007. ECMA had ES4 draft ready which Macromedia/Adobe adapted for flash, only to be abandoned in late 2007 in preference for Harmony (2008). Meanwhile CSS was the only technology that had seen continuous development all this time, though didn't receive browser support till the other two technologies started to awaken from the perceived slumber.

It's important to point out, that innovation for browser technologies hasn't remained stagnant at all, we just needed a new competitor for IE to put everything in motion. IE was tardy and that's going to cost microsoft dearly.

The beast woke up and started flailing.

Ofcourse, Microsoft has a lot of smart people working for them and the internet revival starting in ~2004 and peaking again in 2006 caught their attention. So we got IE7 in 2006 and IE8 in 2009, *opinion* but their intent was mainly to enter round 2 of the browser wars and safe as much of their market share as they can */opinion*. The signal I received here was that Microsoft started to take competitor browser vendors seriously, but they made one huge mistake.

Microsoft did not jump on the standards bandwagon as much as they should and created even more legacy, neither did they create a continuous upgrade scheme and waged round 2 of the browser wars with the wrong strategies. Through failure they learned and IE9 is looking great, in fact, it looks like IE9 might make up for all the ground they lost.

Webstandards are the boxing gloves in this new round of browser wars, Microsoft had doned on their embeded features and OS integration gloves.

So whats the trouble?

Innovation in the holy trinity picked up momentum in the last few years, I had to adjust my personal estimates of when they will become significant for commercial development. My new prognosis is that HTML5, CSS3 and ES5 will become mainstream standards in 2 to 3 years based on the speed technological advancement and more importantly, implementation is going. My estimates and prognosis might carry no weight in the web community, but I think anyone who has to make educated estimates as to what technologies to use in enterprise environments will conclude the same.

When looking at browser statistics, all Microsoft browsers since 5.0 (yes even IE5.0) are still in use today, they're all going to break. They will all be perceived as total and utter garbage and this will reflect on Microsoft and the IE trademark. With IE8, Microsoft is miles behind and IE9 enters the scene way too late. The majority of the IE users will not upgrade to IE9, that's a proven fact and they will all experience a worsening web experience and blame Microsoft.

The 'modern' browsers have had an active upgrade scheme, so the majority of their users are used to upgrading whenever a new version is out, some browsers even automated this upgrade process. Best of all, they're not integrated into the operating system (signifying the power of loose coupling yet again).

History repeats itself, NN was a great browser with many innovations, but websites where build for IE5+ because it was easier to develop for and with aggressive tactics from Microsoft had the biggest market share. Now the shoe is on IE because developers want to move forward and seeing the aggresive action undertaken against IE6 by developers, this will happen. Microsoft painted themselves into a corner and will be in trouble.

What can Microsoft do?

Create and implement an upgrade strategy NOW! Re-educate their user base to upgrade frequently and even more important, work on reducing upgrade costs for companies and organisations.

Whilst most developers are easily anti or pro Microsoft, I personally feel that Microsoft is an important player in our industry wether I like their products or not. It's in our interrest to see Microsoft do the right thing and remain a major player, especially now they appearantly lost the reckless part of their killer approach (pushing Netscape out of the market was their biggest mistake for self preservation imo.) and take on a more participant approach. Companies need competition to stay on top, Microsoft proved that while profitable, eliminating the competition equals social and innovative suicide and will cost dearly later on.

The last thing I want to see for the industry I love, is for example Google winning this round of browser wars and see yet another 5-10 years of internet dark ages.

Filed under: JavaScript No Comments
11Mar/10Off

Presenting objection.js

Quote from 'Design Patterns' from the gang of four.

Favor object composition over class inheritance.

With JSoo I wanted to provide tools for OO JS, but I was still thinking in terms of pseudo classical inheritance. Foolishly I created JSoo to be a prototype constructor and registry and loader. Well the register and loading part of JSoo made it's way to mikado which is still under development and the OO part went into Objection. I had to write Objection since I wanted a cleaner and clearer way of dealing with objects in preparation of ES5.

Presenting objection.js.

Objection is a tiny OO toolbox (just under 2kb minified) that can change the way your write your JS programs and you should at least give it a try if only to prepare yourself for ES5 goodness.

First of all, it offers #create though a teensy bit different from the ES5 (Object.create) implementation. If there's a initialise (or initialize) method on the to-be-cloned object, it will be invoked (without arguments) once the object is created offering an alternative to the pseudo classical constructor. Initialise should only be used to add new property instances to the new object where you don't want property references from the old object (ie. array/object properties). Most arguments passed to constructors are usually property setters, so augment the object through #create rather then using constructor arguments.

Example:

var Mammal = {
   initialise: function(){
      this.sounds.roar = 'some mammals can roar';
      this.roar();
   },
   roar: function(){
      alert(this.sounds.roar);
   }
};
 
var cat = Obj.create(Mammal , {
   sounds: {
      roar: 'miauws'
   }
}); // alerts 'miauws'
cat.roar(); // alerts 'miauws'
 
// intentfully omitting propertiesObject to illustrate that mammal.initialise gets invoked.
var dog= Obj.create(Mammal );
dog.roar(); // alerts 'some mammals can roar'

Why is this better then pseudo classical inheritance and constructors? First of all, we just describe the Mammal object as an object, not as a function and attaching properties to it's prototype. Instead of 'new' we call Objection.create() (Obj is an alias) at which point we can decide to leave the new instance as is or augment it with extra properties through a property descriptor (2nd argument) or we can mixin properties from another object alltogether. So we use reusable packets of properties rather then constructor arguments.

I just added the initialise/initialize method behaviour to mitigate one major ambiguous feature. All inherited/cloned properties are references by default, meaning that an object or array property on the parent object will be exactly the same as on the child object. This feature also manifests itself in the pseudo classical way of creating objects. I might dedicate a post on this in the future.

Another nice method in Objection, is the adapter method, which creates an adapter object to remap method names or add method combiners without changing the original object.

var incompat = {
   halloWereld: function(){
      alert('hello world!');
   },
   dagWereld: function(){
      alert('goodbye world');
   }
};
 
var compat = Obj.adapter(incompat, {
   'hello' : 'halloWereld',
   'bye' : 'dagWereld',
   'helloAndBye' : function(){
      this.halloWereld();
      this.dagWereld();
   }
});
 
compat.hello(); // alerts 'hello world!'
compat.bye(); // alerts 'goodbye world'
compat.helloAndBye(); // alerts 'hello world!' and 'goodbye world'

Possible uses for the adapter method, is to make all thos Selector engines that all choose different method names (grrr) plugable into all your programs. Simply remap 'select', 'find', 'query' to 'qsa' or whatever you find logical for a selector method ;)

Obviously, we also want to check if an object inherits from another object and though we can use 'isPrototypeOf' to do this. I've always found inheritance an obscure name, I mean, a ferarri IS a car, a cat IS a mammal...

var Mammal = {};
var Insect = {};
var Fish = {};
var Cat = Obj.create(Mammal);
var Dog = Obj.create(Mammal);
var Felix = Obj.create(Cat);
 
// #is
Obj.is(Felix, Cat); // true
Obj.is(Felix, Dog); // false
// #isAll
Obj.isAll(Felix, Cat, Mammal); // true
Obj.isAll(Felix, Insect, Cat); // false
// #isSome
Obj.isSome(Felix, Insect, Cat); // true
Obj.isSome(Felix, Dog, Insect); // false

Clear as rain isn't it?

And now finally, the #factory method, I'll just post the example right away.

var BasePizza = {
   orders: function(nr){
      this.total = this.total + (nr * this.price);
      this.ordered = this.ordered + nr;
   },
   ordered: 0,
   total: 0
};
 
var pizzaFactory = Obj.factory(BasePizza);
 
pizzaFactory.addType('hawai', {
   pineapple: true,
   ham: true,
   price: 12
});
 
pizzaFactory.addType('peperoni', {
   peperoni: true,
   price: 10
});
 
pizzaFactory.addType('delux', {
   olives: true,
   broccoli: true,
   anjovis: true,
   extraCheese: true,
   price: 14
});
 
var bart = pizzaFactory.create('hawai');
bart.orders(1);
 
var lisa = pizzaFactory.create('delux');
lisa.orders(1);
 
var homer = pizzaFactory.create('peperoni');
homer.orders(3);
 
var total = bart.total + lisa.total + homer.total; // 64

I could go on and on about possibilities and how this way of programming makes much more sense, instead, I'll just offer up some links and safe more indepth info for future articles.

Further documentation can be found here:
http://wiki.github.com/bgerrissen/objection/

Downloads:
http://github.com/bgerrissen/objection/downloads

Enjoy ;)

Filed under: JavaScript No Comments
16Jan/10Off

Mea culpa, it was obvious.

Kind guys in prototype IRC channel pointed me to this article http://yura.thinkweb2.com/named-function-expressions/ which explains what's happening.
qFox from fronteers IRC also kicked me in the groins for not knowing the difference between expressions and declarations.

Basically, declarations are compiled before anything else inside a scopeblock, causing the "functions float to top" feature.

1
2
3
4
test(); // alerts "Hello world!"
function test() { // declaration
   alert("Hello world");
}

This ofcourse creates ambiguous code and should not be done if you want your code to be clear and appearant.
Instead declare functions as part of an expression by assigning them to variables or properties.

1
2
3
4
5
test(); // alerts undefined
var test = function test() { // expression
   alert("Hello world");
}
test(); // alerts "Hello world!"

The fact that it seems to work in FireFox is because they foolproofed it and now I get it, I feel they shouldn't have.
Though the declaration spec creates ambiguity, it's the spec, it does exactly as ordered and a browser should not fix developer mistakes and incompetence.
(Yeh, I was incompetent myself for not knowing this! I admit it! sigh)

I read a lot of books, written a lot of JS code and read oogles of JS articles on the web and this little piece of (in hindsight) common wealth information always eluded me. So leaving my rather newbish blog post up so other devs who run into this, will have yet another article to explain what they're encountering.

Filed under: JavaScript No Comments
16Jan/10Off

If/else + functions = madness

My code style might not be perfect, but the following code should be pretty straight forward in what to expect right?

if(true) {
   function test() {
      alert("SUCCESS!");
   }
} else {
   function test() {
      alert("FAIL!");
   }
}
test();
// alerts "SUCCESS!" in FireFox (3.5.7)
// alerts "FAIL!" in IE8, Opera 9.62, (win) Safari 4.0.4
// need to install and test this in google's Chrome still!

Whats going on here???!

I first encountered this "feature" in Safari and thought it was a local incident, though to my suprise, I reproduced it in other browsers as well!

Function literals float to the top of the scopeblock, however functions inside a failed clause, should be ignored by the interperter.
Am I missing the reason why so many browser vendors implemented it this way?
Is FireFox/Mozilla actually the odd duck here? And if so, for the love of god, why?
Is this a recent development? A discrepancy introduced by engines competing eachother over speed?

Also kinda weird that after years of JavaScript, I encounter this now...
Or is this something I never encountered before untill I started bloating my code for better readability, structuring and reducing if/else expressions?

Sure, we can mitigate this easily by changing our coding style and never declare functions through the literal notation, assigning anonymous functions to variables.

if(true) {
   var test = function() {
      alert("SUCCESS!");
   }
} else {
   var test = function() {
      alert("FAIL!");
   }
}
test();
// alerts "SUCCESS!" everywhere =/

But that's just plain daft... using function literals is pretty straightforward and everyone will trip constantly over this discrepancy when trying to write clean/clear code.
Now I have to explain to Java developers learning JS that they should avoid using function literal declarations...

Will investigate further.

Filed under: JavaScript No Comments