I'm just going to go through the basics first just in case, though you probably already know a little of this, if only by intuition.
------------------------------------
There are many names for function literals. Common ones include:
- function literal
- anonymous function
- function expression
- lambda
- lambda expression
(The latter two are often used for a certain kind of function.)
A function literal is the following:
Code:
function(params) {code}
Notice there is no name for the function. In Javascript, functions are objects, meaning that you can assign them to variables.
Code:
function a() {alert("a");}
var b = a;
b();
Knowing this, you can define a brand new function by doing:
Code:
var add = function(x, y) {
return x + y;
};
alert(add(1, 2));
This is what we are doing with the el.onclick = function() {};
Seeing that you can assign functions to variables, it should be apparent that you can pass them to functions as well. After all, paramaters are variables.
Code:
alert([2,1,3,4,1,1].sort(function(a, b) {
if(a > b)
return 1;
if(a < b)
return -1;
return 0;
}));
What happens when you create a function inside a function? At first glance, it seems like nothing special. Note that the proper way of creating a function in any statement or function (when defining a function within a construct delimited by optional or mandatory curly brackets) is using the function expression syntax and not ordinary function syntax.
Code:
function a() {
var b = function() {
alert("b");
};
b();
}
a();
//b(); // uncommenting this statement gives an error
Alright, what about . . .
Code:
function a(x) {
var y = "y from a";
var b = function() {
alert(x);
alert(y);
};
b();
}
a("arg from a's x");
In the above example, the inner function knows all of a's local variables. Okay, now to the real question. What happens if the function a dies, but the function b lives? You might be wondering how this is possible, but observe:
Code:
function a(x) {
var y = "y from a";
return function() {
alert(x);
alert(y);
};
}
var val = a("arg from a's x");
val();
Clearly the function a has finished doing its work by the time val has a value assigned to it. Also, you have most likely heard about how the local variables in functions die out after the calling function ends from sources all over the place. Else your computer would soon run out of memory! Well, it turns out the Javascript (and in various other languages that support first-class functions . . . aka, where functions are treated like any other variable) has a built-in construct called a closure.
A closure is basically where local variables from all surrounding functions of a function remain in existence as long as the inner function lives. This is why the returned function stored in val knows about the variables x and y.
Code:
function a(x) {
return function() {
alert(x++);
};
}
var v1 = a(0);
var v2 = a(99);
var v3 = v1;
v1();
v1();
v2();
v2();
v3();
The above code also reveals to us that two different closures were created, each housing a different set of x's. As a matter of fact, even though v1 and v2 manage to change their x's, the change is only be seen in itself. (Remember though that v1 and v3 are the exact same function. In the case of changing x, the change would be seen between the two.)
Let's side track for a moment and go back to anonymous functions. There are situations where a function literal is never assigned to anything. In this case, it must execute itself. Here is the syntax:
Examples:
Code:
(function() {
alert("self-executing function literal!");
})();
(function(x, y, z) {
alert(x + y + z);
})(1, 2, 3);
--------------------------------
Code:
imgs[i].onclick = (function(img, dd) {
return function() {
toggleSection(img, dd);
};
})(imgs[i], dds[j]);
Aha! The self-executing function literal! The point of this is to create a closure binding the img and dd values so the event handler function remembers them, so it in turn can use them for toggleSection.
If you are sharp, you might realize that those aren't the only variables bound by the closure. (BTW: Is it correct to use closure as a verb? Aka: Saying "closed" as in "bound by the closure"?) In that case, why not simply do:
Code:
imgs[i].onclick = return function() {
toggleSection(imgs[i], dds[j]);
};
The problem is that i and j change, and by the time the loop has completed, all the event handling functions you created will have the same i and j values. Oops! (In this case, they would also exceed the array bounds to boot.)
----------------------
i'm not certain if [Trinithis is] using currying in the code provided for my problem-- but if it is, it appears to be some variation-- a bit unlike those in the examples at the references provided (above, by Trinithis), though similar enough to inspire curiosity. ;-)
You aren't quite far off the track there
. It isn't currying. Despite this, it is a form of partial application . . . kinda. (Currying is just a mechanism to implement partial application.)
Note: If any of the examples don't work, please let me know.
Bookmarks