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

Friday, March 02, 2007

function, (function) or var function?

Few days ago Dustin Diaz wrote about function declaration ambiguity.

In my opinion the best way to declare a function (class) is the classic way

function MyClass(){
// constructor
};

The reason is simple: a class could be a very big function and some version of Explorer could generate an error if big function is declared using

var MyClass = function (){
// constructor
};

However this post talks about other function "strange things", expecially about usage of brackets after function declaration.


function MyTest(){alert(arguments.length)}();

This will produce an error, exactly a Syntax error.
The "strange thing" is that You could do something inside brackets then function will not be called and syntax error will disappear.

function MyTest(){alert(arguments.length)}
(alert(MyTest));

This is a strange "feature" and it's different from this one:

(function MyTest(){alert(arguments.length)})
(alert(MyTest));

This code will produce a reference error because MyTest, declared inside brackets, has not a global scope then MyTest is correctly undefined.
This is one of the best way to create a lambda function inline too.

var len = (function(){return arguments.length})(1,2,3);

As You know len variable will not be a function but a Number with value equal to 3.
The strange thing is that "var" keyword doesn't produce the same result of regular function.

var MyTest = function(){alert(arguments.length)}();

This example will not produce any error and function is called correctly even without arguments.
Next example shows that function works correctly but it's not the value of MyTest variable.

var MyTest = function(){
alert([arguments.length, arguments[0]])
}(MyTest);
alert(MyTest); // undefined

That's why We need to return called function.

var MyTest = function(){
alert([arguments.length, arguments[0]]);
return arguments.callee
}(MyTest);
MyTest(MyTest);

Finally You could use these informations to create a real-time interval.

onload = function(){

var interval = function(){
document.body.appendChild(document.createTextNode("\n".concat(Math.random() * 1234567)));
return interval ? 0 : setInterval(arguments.callee, arguments[0]);
}(2000);

setTimeout(function(){
clearInterval(interval);
}, 20000);
};

This code will call 10 times the function (20/2 seconds) and not 9.
Do You think this is interesting?

No comments: