Over on my other blog I’ve just published a new technique for executing a piece of JavaScript once a page has finished loading. Here’s the code:
1 | function addLoadEvent(func) { |
2 | var oldonload = window.onload; |
3 | if (typeof window.onload != 'function') { |
4 | window.onload = func; |
5 | } else { |
6 | window.onload = function() { |
7 | oldonload(); |
8 | func(); |
9 | } |
10 | } |
11 | } |
12 | |
13 | addLoadEvent(nameOfSomeFunctionToRunOnPageLoad); |
14 | addLoadEvent(function() { |
15 | /* more code to run on page load */ |
16 | }); |
view plain | print |
A closure consists of a function along with the lexical environment (the set of available variables) in which it was defined. This is a remarkably powerful concept, and one commonly seen in functional programming languages such as JavaScript. Here’s a simple example of closures in action:
1 | function createAdder(x) { |
2 | return function(y) { |
3 | return y + x; |
4 | } |
5 | } |
6 | |
7 | addThree = createAdder(3); |
8 | addFour = createAdder(4); |
9 | |
10 | document.write('10 + 3 is ' + addThree(10) + ''); |
11 | document.write('10 + 4 is ' + addFour(10)); |
view plain | print |
createAdder(x)
is a function that returns a function. In JavaScript, functions are first-class objects: they can be passed to other functions as arguments and returned from functions as well. In this case, the function returned is itself a function that takes an argument and adds something to it.createAdder
the integer 3, you get back a function that will add 3 to its argument. If you pass 4, you get back a function that adds 4. The addThree and addFour functions in the above example are created in this way.Let’s take another look at the
addLoadEvent
function. It takes as its argument a callback function which you wish to be executed once the page has loaded. There follow two cases: in the first case, window.onload
does not already have a function assigned to it, so the function simply assigns the callback to window.onload
. The second case is where the closure comes in: window.onload has already had something assigned to it. This previously assigned function is first saved in a variable called oldonload. Then a brand new function is created which first executes oldonload, then executes the new callback function. This new function is assigned to window.onload
. Thanks to the magical property of closures, it will “remember” what the initial onload function was. Further more, you can call the addLoadEvent function multiple times with different arguments and it will build up a chain of functions, making sure that everything will be executed when the page loads no matter how many callbacks you have added.Closures are a very powerful language feature but can take some getting used to. This article on Wikipedia provides more in-depth coverage.
No comments:
Post a Comment