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?

+3


source to share


5 answers


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.

+1


source


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.

+1


source


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(){};

      

+1


source


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.

+1


source


In this case, the function will not be raised. The lifter compiles it before running any other code. Lifting is carried out only for functional blocks.

I see no reason to do this here. You lose lifting, older versions of IE have memory leaks and use extra bytes.

0


source







All Articles