There is a lot of power in Javascript syntax. One of those powerful things is that of Javascript Anonymous Functions.
But what is an Anonymous Function in Javascript?
It is a function that does not have a name or one that has been hidden out of scope around its creation.
A common use of a Javascript Anonymous Function is to guarantee that the same variable names or function names are not already used within the same document.
In the below code block, we define one variable and two functions.
var my_number = 31;
var get_the_meaning_of_life = function() {
return "<The meaning of life goes here>";
};
var something_else = function(something) {
return "meh "+something;
};
Now, how do we wrap this in an anonymous function? Simply!
(function() {
var my_number = 31;
var get_the_meaning_of_life = function() {
return "<The meaning of life goes here>";
};
var something_else = function(something) {
return "meh "+something;
};
});
We can see that anything that lives within the following block becomes an anonymous function:
(function() {
//.. put your code in here!
});
Ok, this works pretty well, but we are not able to access it anymore if we ran this code. So how do we do this?
(function(w) {
var my_number = 31;
var get_the_meaning_of_life = function() {
return "<The meaning of life goes here>";
};
var something_else = function(something) {
return "meh "+something;
};
window['my_number'] = my_number;
window['get_the_meaning_of_life'] = get_the_meaning_of_life;
window['something_else'] = something_else;
})(window);
Note the important addition of the (window)
caller at the very end of this example. Along with the w
variable being assigned in the first line of the caller function.
You can pass as many parameters as you like, as long as you register them in the caller function.
So far our example works but seems a little useless. So instead we will try and create something more useful:
(function(w) {
var ouo = {}
ouo['my_number'] = 31;
ouo['get_the_meaning_of_life'] = function() {
return "<The meaning of life goes here>";
};
ouo['something_else'] = function(something) {
return "meh "+something;
};
window['our_unique_object'] = ouo;
})(window);
Now we can use it outside of this anonymous function as:
console.log(window.our_unique_object.my_number);
// returns 31
Because it’s bound to the window
object, we could actually just call it as follows:
console.log(our_unique_object.my_number);
// returns 31
This is ideal as now we have a decent way to package a list of variables and functions under a namespace called our_unique_object
. This could be your company or project name.
If you’ve been following along, we don’t actually make use of the window
->w
variable we pass in, so we can either use it, or get rid of it, let’s do the latter, but keep our caller:
(function() {
var ouo = {}
ouo['my_number'] = 31;
ouo['get_the_meaning_of_life'] = function() {
return "<The meaning of life goes here>";
};
ouo['something_else'] = function(something) {
return "meh "+something;
};
window['our_unique_object'] = ouo;
})();
Multiple Levels of Anonymous Functions
As you have probably guessed, it’s possible to have multiple layers of Anonymous Functions:
(function(input) {
var a = (function(say) {
return "Say "+say;
})(input);
window['b'] = a;
})("hello");
Let’s try and use this:
b
// returns "Say hello"
b()
// Uncaught TypeError: b is not a function
“Uncaught TypeError: b is not a function ”
This is interesting! It immediately evaluated the a
variable with the input value, because we added the (input)
section.
If we made a change as follows (to not automatically evaluate it):
(function(input) {
var a = (function(say) {
return "Say "+say;
});
window['b'] = a;
})("hello");
And tried to run it:
b
// ƒ (say) {
// return "Say "+say;
// }
b()
// "Say undefined"
b("world")
// "Say world"
This is because we have lost our input
scope due to the nature of anonymous functions and the event loop.
We now need to call the function ourselves with some input data of our own.
Closing comments
Anonymous Functions are a very powerful feature in Javascript that lets us wrap dynamic code into static in-memory objects. They also provide the ability to create namespaces so that we can both hide and organise our code as desired.