The difference between the two functions? ("function x" vs "var x = function")
The first one is a named function statement, the second one assigns an anonymous function expression to a variable.
The function statement is added to its scope immediately - you don't need to run it before being able to call it, so this works:
var y = sum(1, 2);
function sum(x, y) {
return x + y;
}
But the function expression is only assigned to the variable when the code is executed, so this doesn't work:
// Error here because the function hasn't been assigned to sum yet.
var y = sum(1, 2);
var sum = function(x, y) {
return x + y;
}
An advantage of the expression form is that you can use it to assign different functions to the expression at different points - so you can change the function, or use a different one under different conditions (such as depending on the browser being used).
An advantage of a named function statement, is that debuggers will be able to display the name. Although, you can name function expressions:
var sum = function sum(x, y) {
return x + y;
}
But this can be confusing since the two names are actually in different scopes and refer to different things.
The first is known as a named function where the second is known as an anonymous function.
The key practical difference is in when you can use the sum function. For example:-
var z = sum(2, 3);
function sum(x, y) {
return x+y;
}
z
is assigned 5 whereas this:-
var z = sum(2, 3);
var sum = function(x, y) {
return x+y;
}
Will fail since at the time the first line has executed the variable sum has not yet been assigned the function.
Named functions are parsed and assigned to their names before execution begins which is why a named function can be utilized in code that precedes its definition.
Variables assigned a function by code can clearly only be used as function once execution has proceeded past the assignment.
The first tends to be used for a few reasons:
- The name "sum" shows up in the stacktrace which makes debugging easier in many browsers.
- The name "sum" can be used inside the function body which makes it easier to use for recursive functions.
- function declarations are "hoisted" in javascript, so in the first case, the function is guaranteed to be defined exactly once.
Semicolon insertion causes
var f = function (x) { return 4; } (f)
to assign 4 to
f
.
There are a few caveats to keep in mind though. Do not do
var sum = function sum(x, y) { ... };
on IE 6 since it will result in two function objects being created. Especially confusing if you do
var sum = function mySym(x, y) { ... };
According to the standard, function sum(x, y) { ... } cannot appear inside an if block or a loop body, so different interpreters will treat
if (0) {
function foo() { return 1; }
} else {
function foo() { return 2; }
}
return foo();
differently. In this case, you should do
var foo;
if (0) {
foo = function () { return 1; }
} ...
The two code snippets you've posted there will, for almost all purposes, behave the same way.
However, the difference in behaviour is that with the second variant, that function can only be called after that point in the code.
With the first variant, the function is available to code that runs above where the function is declared.
This is because with the second variant, the function is assigned to the variable foo at run time. In the first, the function is assigned to that identifier foo at parse time.
More technical info
Javascript has three ways of defining functions.
- Your first example is a function declaration. This uses the "function" statement to create a function. The function is made available at parse time and can be called anywhere in that scope. You can still store it in a variable or object property later.
- Your second snippet shows a function expression. This involves using the "function" operator to create a function - the result of that operator can be stored in any variable or object property. The function expression is powerful that way. The function expression is often called an "anonymous function" because it does not have to have a name,
- The third way of defining a function is the "Function()" constructor, which is not shown in your original post. It's not recommended to use this as it works the same way as eval(), which has its problems.