Thursday, February 22, 2007

Functions as Objects [Javascript 2.0]

JavaScript just about everything that is not primitive data is an object, and functions are no exception. Thus, it is possible to define functions in a much different way than we have seen up until now, by using the keyword new and the Function object. For example, here we define a function and assign it to the variable sayHello. Notice that Function is capitalized, as we are talking about creating an instance of JavaScript’s built-in Function object:
var sayHello = new Function("alert('Hello there');");
Later on we can then use the assigned variable sayHello just like a regular function call:
sayHello();
Because functions are first-class data types, the function can even be assigned to another variable and used by that name instead.
var sayHelloAgain = sayHello;
sayHelloAgain();
To expand the example, we could define a function with a parameter to print out
var sayHello2 = new Function("msg","alert('Hello there '+msg);");
and call it:
sayHello2('Thomas');
The general syntax for the Function() constructor is
var functionName = new Function("argument 1",..."argument n",
"statements for function body");
As we have already seen, functions can have zero arguments, so the actual number of parameters to Function() will vary. The only thing we have to do is pass, as the final argument, the set of statements that are to execute as the body of the function.
If you have coded JavaScript before, you may not have seen this style of function definition and might wonder what its value is. The main advantage of declaring a function using the new operator is that a script can create a function after a document loads.
Note
Since JavaScript 1.2, you can create functions using new anywhere in the script; previously, you could only define them globally and not within a block such as those associated with if statements, loops, or other functions.
Function Literals and Anonymous Functions

As we have seen in the previous section, defining a function using a new operator doesn’t give the function a name. A similar way to define a function without a name and then assign it to something is by using a function literal. Function literals use the function keyword but without an explicit function name.
A simple use of a function literal is
var sayHi = function(name) { alert('Hi my name is '+name); };
sayHi('Fritz');
We assign a function literal to sayHi and can then use it as we would any other function.
The previous example wasn’t particularly compelling, but function literals do have their uses. Their primary use is when creating methods for user-defined objects. A simple example showing function literals used in this manner is presented here. We have defined a function SimpleRobot that is used as an object constructor—a function that creates an object. Within the function we have defined three methods that are assigned function literals.
function SimpleRobot(robotName)
{
this.name = robotName;
this.sayHi = function () { alert('Hi my name is '+this.name); };
this.sayBye = function () { alert('Bye!'); };
this.sayAnything = function (msg) { alert(this.name+' says '+msg); };
}
It is now simple to create an object using the new operator in conjunction with our SimpleRobot constructor function, as shown here:
var fred = new SimpleRobot("Fred");
Invoking the various functions, or, more correctly, methods, is simply a matter of invoking their names, similar to plain function calls:
fred.sayHi();
fred.sayAnything("I don't know what to say");
fred.sayBye();
The result of the previous example is shown here:

You might wonder why not just use the following new-style syntax in the constructor function:
function SimpleRobot(robotName)
{
this.name = robotName;
this.sayHi = new Function ("alert('Hi my name is '+this.name); ");
this.sayBye = new Function ("alert('Bye!'); ");
this.sayAnything = new Function("msg","alert(this.name+' says '+msg);" );
}
The reality is you could, and everything would still operate properly. The only downside to this approach is that it might use substantially more memory, as new function objects are created every time you create a new object.
A similar kind of nameless function doesn’t even get assigned a name at any time. An anonymous function is one that cannot be further referenced after assignment or use. For example, we may want to sort arrays in a different manner than what the built-in sort() method provides; in such cases, we may pass an anonymous function:
var myArray = [2, 4, 2, 17, 50, 8];
myArray.sort( function(x, y)
{
// function statements to do sort
}
);
The creation of an anonymous function is in this case carried out by using a function literal. While the function is accessible to sort() because it was passed a parameter, the function is never bound to a visible name, so it is considered anonymous.

No comments :