Assigning a non-anonymous function to a variable
The book I am reading has a page about recursion with the following code:
var hanoi = function hanoi(disc, src, aux, dst){
if (disc > 0){
hanoi(disc - 1, src, dst, aux);
document.writeln('Move disc ' + disc + ' from ' + src + ' to ' + dst);
hanoi(disc - 1, aux, src, dst);
}
};
Edit: Question to rephrase. In this example, what is the difference between var hanoi = function hanoi(){}
and just using var hanoi = function(){}
?
eg. why is Hanoi declared as a variable but also the function is called Hanoi? Why double hanoi?
source to share
There is a very subtle point here. In the next two examples, the function body is the same as your original. In one case, an anonymous function is used, and in the other, the function is called hana, as in the original.
var hanoi2 = function hanoi(disc, src, aux, dst){
if (disc > 0){
hanoi(disc - 1, src, dst, aux);
document.writeln('Move disc ' + disc + ' from ' + src + ' to ' + dst);
hanoi(disc - 1, aux, src, dst);
}
};
var hanoi3 = function(disc, src, aux, dst){
if (disc > 0){
hanoi(disc - 1, src, dst, aux);
document.writeln('Move disc ' + disc + ' from ' + src + ' to ' + dst);
hanoi(disc - 1, aux, src, dst);
}
};
Will this work? Note that the function body still refers to "hanoi", not "hanoi2" or "hanoi3".
It turns out that hanoi2 will work, but hanoi3 won't. This is because when you call a function, the function name is available inside the scope of the function body. So, both in your original example and in hanoi2, "hanoi" inside a function does not refer to the global variable hanoi, but to the named function hanoi.
So, the answer to your question is that since the function uses recursion, the named version is slightly more reliable than the anonymous version, which modifies your code.
source to share
First, you don't need to specify a function. It's enough:
var hanoi = function() { /*code*/ }
However, there is a difference when dealing with variable hoisting and the way functions are declared.
For example, the following code will work without error:
foo();
function foo(){
console.log('foo');
}
whereas this will fail:
foo();
var foo = function(){
console.log('foo');
}
In the second example, there will be an error with something like "undefined is not a function".
Function declarations ( function foo() {}
) are hoisted with the full function body, while var statements only have the variable hoisted at the top of the scope.
EDIT: Please note that there is some wiggle room here:
var hanoi2 = function hanoi() { /*code*/ }
will create two variables hanoi
and hanoi2
that will refer to the same function. However, hanoi
it will be raised as a complete function, but hanoi2
will not.
source to share
var hanoi = function hanoi(){}
creates an expression with a named function and assigns it to a variable that has the same name as the expression.
function hanoi(){}
declares a function.
There is a difference in how the two are lifted. For example, you can call a declared function before the declaration. But you cannot do the same with a named function expression.
//ok
var joe = new Person();
function Person() {};
//error
var joe = new Person();
var Person = function Person(){};
source to share
This is the difference between a FunctionExpression
and a FunctionDeclaration
respectively.
- In the first case, the function is an expression. What for? Only variables can be assigned to a variable.
- In the second case, the function is a declaration. What for? It is not used in the context of an expression.
The only noticeable difference is what you can use FunctionDeclaration
before it appears in the current area. This is because ads are rendered in JavaScript. For example:
alert(f()); // Error: undefined is not a function.
var f = function f() { return "Hello World!"; };
Here, when we call f
, the variable f
is not yet defined. Hence it throws an error.
alert(f()); // Hello World!
function f() { return "Hello World!"; };
Here we can call f
before it appears in the current scope because the declarations in JavaScript are hoisted (i.e. brought to the beginning of the scope).
Personally, I prefer to use function declarations instead of function expressions. You can even place function declarations after the statement return
in the function and still call them before the statement return
. This allows you to write readable modules using the module template.
source to share