-2

I'm learning javaScript through the book" Professional JavaScript for Web developers 3rd Edition". And In section 7.1 of Chapter 7, the author puts an example to realize the decoupling between executing function and the function name:

var factorial = (function f(num) {
    if (num <= 1) {
        return 1;
    } else {
        return num * f(num - 1);
    }
});

The code above does well whether in strict mode or not. As I saw before, the code worked in two steps:

First: declare the function f

function f(num) {
    if (num <= 1) {
        return 1;
    } else {
        return num * f(num - 1);
    }
}

Second: assign the function name f to the variable factorial

var factorial = f;

So I thought it's feasible to call the function f directly in the example below.

var factorial = (function f(num) {
    if (num <= 1) {
        return 1;
    } else {
        return num * f(num - 1);
    }
});

f(5);

But in fact, it doesn't work. The console said "f is not a function"; Why? Is there any thing to do with closure?

nick zoum
  • 6,639
  • 5
  • 26
  • 63
chenxy
  • 1
  • 1

1 Answers1

1

var factorial = function f(){}; is not the same as function f(){} var factorial = f;

When using function expressions you can only access the function by the name you gave it from inside the function.

var factorial = function f(num) {
    if (num <= 1) {
        return 1;
    } else {
        return num * f(num - 1);
    }
};
console.log(typeof f);
console.log(factorial(5));

If you first define the function and then assign it to a variable then the function will be accessible using both names by everyone in the scope.

function f(num) {
    if (num <= 1) {
        return 1;
    } else {
        return num * f(num - 1);
    }
};

var factorial = f;
console.log(typeof f);
console.log(factorial(5));

In the first example f does not get hoisted. The name f only exists inside the function. In the second example f gets hoisted. The name f exists in the global scope.

nick zoum
  • 6,639
  • 5
  • 26
  • 63