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

Tuesday, October 03, 2006

Packer Friendly JavaScript

Mario tells me a thing on this post comments that could be a good point to analyze.

Since I've known Dean Edwards packer, I've started to write code in a different way.
The reason is simple: code is elegant enought and I could pack or unpack them quickly.

The "big one rule" to write compressors friendly code is the usage of the semi-colon ";" instead of new line at the end of each line (sure, only where it's necessary).

In this way your code could be crunched without problems from a big list of js compressors.

Let me show an example

// "typical" code

function a() {
return "a"
}

function b(c) {
c = "b" + c
return c
}

These functions are not a problem for javascript parser because it reads new lines as semi-colon (or better ... as end points) but to be sure that a compressor will not have problems, You need to think that every code must be parsed correctly inline, trimming every space or tab.
In this case, function a has no problems while function b has one.

// function a can be wrote inline
function a() {return "a"}

// function b cannot be wrote inline
function b(c) {c = "b" + creturn c}

There's any end char after c var, then creturn is not c and then return.
What is the solution ? You know it, just a semi-colon :)

function b(c) {c = "b" + c;return c}

return c doesn't need any semi-colon because curly brackets tells to code parser that in that point the execution ends.
If You have an if, while, else if, else, for You don't need to add anything before last curly bracket.

function c(d) {
if(d) {
d = true
}
return d
}

But if You don't use curly brackets for single operations after some expression, the use of semi-colon is a must.

function c(d) {
if(d)
d = true; // remember
return d
}

I think is really important to remember that there is a particular case where curly brackets requires a semi-colon at the end and this case is a generic object declaration.

var obj = {}
var arr = []
// do you need an error ? try this
// var obj = {}var arr = []

// correct way
var obj = {}; // remember
var arr = [];

If you need more than one temporary scope variable you could use the colon "," to concatenate each var declaration.
In this case the semi-colon is not necessary between two variables.

var obj = {}, arr = [];

That's all about curly brackets but I would suggest to use a semi-colon after every end bracket "}", to be sure that there aren't problems and to write a more linear code.

function a(a) {
return a
};

function c(d) {
if(d) {
d = true
};
return d
};

var obj = {}; // remember

Talking about vars You can see that a semi colon is necessary after each declaration.

// not friendly way
var str = "test"
var num = 1
var boo = false

// friendly way
var str = "test"; // remember
var num = 1; // remember
var boo = false; // remember

And as I've said, using a colon for each temporary var requires a semi-colon only at the end.

var str = "test", num = 1, boo = false; // remember

Other characters that require a semi-colon at the end are parentheses.

// anonymous function, not friendly way
(function(){
alert("anonymous")
})()

// friendly way
(function(){
alert("anonymous")
})(); // remember

Sure, semi-colon is not necessary if you send anonymous function to another one but in other cases is really important to rememeber that every end parenthese ")" needs a semi colon, such at the end of this alert example.

alert((function(){return "something"})());

With class object declaration You could forget parenthese but these should be wrote at the end of class name, then rememebre to add a semi-colon.

// generic class
function MyClass(){
this.ready = true
};

// generic class objects
var c1 = new MyClass(),
c2 = new MyClass; // remember

// generic check
alert(c1.ready === c2.ready); // will be "true"

I think there's only last case where semi-colon is necessary and this is the switch operator.

// not friendly way
switch(true) {
case false:
break
default:
alert("true");
break
};

// friendly way
switch(true) {
case false:
break; // remember
default:
alert("true");
break
};

Only the last break could be wrote without the semi-colon, because as is for everything before each end curly bracket "}".
The final point is that semi-colons are javascript friends, then is always better one more than one miss.

I think this is all you need to know about compressors friendly code and as You can see adding just a semi colon while You create is neither a bad practice nor less elegant than other ways but Your script will be released as packer ready :-)



[ edit ]
Just a simple addiction that should be a mistake ... with if, else and else if or where curly brackets are more than one operation, You don't have to put any semi colon at the end of closed bracket.

if(something) {
test = true
} // remember no semi-colon
else {
test = false
};


try {
something()
} // remember no semi-colon
catch(e) {
alert(e);
};

No comments: