A little while ago I talked about creating private variables and methods in JavaScript. This works, but is not necessarily efficient: each instance of the class creates new copies of the members. While that may be exactly what you want for instance variables (think of partNum
in the old examples) it is not always ideal.
The complexity jumps significantly, though. So I’m dividing this half into two parts.
To get started, we need to forget about all this Object-Oriented Programming for a minute and look at some of the neat tricks you can do with functions in JavaScript.
Update:Part 2 is now available.
First, let’s take a look at a few ways to define a function in JavaScript:
1.
function oneFunction ()
2.
{
3.
// function body goes here
4.
}
5.
6.
var anotherFunction = function()
7.
{
8.
// function body goes here
9.
};
The first example, `oneFunction` should be familiar to programmers from most languages. The second one is completely equivalent, but works slightly differently. In this case, the right-hand side, a function, is being assigned to the left-hand side, the var `anotherFunction`.
Remember that in JavaScript, functions are first-class objects, just like everything else, so can be declared with the var
keyword. They can also be passed to other functions as arguments, or returned from functions.
Now let’s take a brief look at parentheses. What do parentheses really do? Essentially, they evaluate and return whatever expression is inside them. For example:
1.
var five = (5);
2.
// the expression is "5"
3.
4.
var nine = (2 * 4) + 1;
5.
// "2 * 4" is evaluated and returned as "8"
6.
7.
var nottrue = (true || false) && false;
8.
// "true || false" evalutes to "true"
9.
10.
var thirty = ((5*5)-10)*2;
11.
// "5*5" is evaluated, then returned as 25 to 25-10,
12.
// which evaluates to 15, which is returned and doubled
So parentheses are slightly more powerful than the simple grouping operation we associate with them. Sometimes we see examples like this, which may be more illustrative:
1.
function checkName (name)
2.
{
3.
return(name==‘admin’);
4.
}
So what happens if we combine parentheses’ ability to evaluate and return code with our ability to define functions as an expression?
1.
var aFunc = (function(){/*…*/});
Of course, this is just the same as `anotherFunction` above, but you can see that the right-hand side “returns” a function. Let’s do something a little different now:
1.
(function(name){
2.
alert("Hello, "+name+"!");
3.
})("World");
What’s going on here? The first set of parentheses [`(function ... )`] evaluate and return the code inside, creating a function. The last set [`("World")`] are then *calling* the function created by the first set. Immediately.
This is a powerful technique, but has certain limits. The interior function is executed immediately on creation, which means the DOM will probably not be loaded yet. Once the function is executed, it is lost. Trying to save it in the left-hand side of an equation will only save the return value of the function, not the function itself. For example:
1.
var aFunc = (function(){
2.
return"I’m not a function!";
3.
})();
4.
alert(aFunc); // Alerts "I’m not a function!"
But, remember what I said about functions as first-class objects? It means we can use one function as a return value from another function:
1.
var bFunc = (function(){// 1
2.
returnfunction(){// 2
3.
alert("Hello, World!");
4.
};
5.
})(); // 3
The outer function (1) is executed immediately (3), and the var `bFunc` stores its return value, which is the inner function (2). So now, `bFunc` is a function, and calling `bFunc()` will alert “Hello, World!”.
We’ll stop for now. If this technique is new to you, play with it for a while. If not, just hang tight and I’ll get to Part 2 soon enough.