Why does the function name inside a named function in JavaScript no longer refer to the function itself?

StackOverflow https://stackoverflow.com/questions/20942044

Pergunta

Consider the following named function:

function f() {
    return f.apply(this, arguments);
}

If you call this function normally it would result in a stack overflow as expected. Not very interesting. So let's do some magic:

var g = f, f = alert;

Now if you call f it will simply alert the first argument. However if you call g it will still alert the first argument. What's happening? Shouldn't calling g result in a stack overflow?

What I understand is that inside the function f (now g) the variable f is no longer bound to f. It becomes a free variable. Hence inside f the variable f now points to alert.

Why does this happen? I would expect the function name inside a named function to always refer to the function itself. I'm not complaining. It's actually pretty cool. I'm just curious.

Foi útil?

Solução

When you do:

var g = f

This is effectively the same as:

var g = function () {
    return f.apply(this, arguments);
}

However, since you reassigned f it no longer points to the original function, it now points to alert. Looks like it's working as designed.

Outras dicas

As mentioned by other answers, it's as designed. Basically, apart from hoisting, the declaration is doing this:

var f = function () {
    return f.apply(this, arguments);
}

That is to say, the value of f is not resolved at the declaration but rather during the function call. Which is why you're seeing what you're seeing.

But there is a way to force it to behave the way you want: use a named function expression. A named function expression looks like a declaration but is not due to the function being declared as an expression.

For example, in the following:

var ff = function f () {
    return f.apply(this, arguments);
}

The value of f is bound at the declaration and will be immune to reassignment. In a named function expression, the function name is only defined inside the expression and therefore behaves more like a closure rather than a variable.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top