[英]Why does the function name inside a named function in JavaScript no longer refer to the function itself?
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. 现在,如果调用
f
,它将仅alert
第一个参数。 However if you call g
it will still alert
the first argument. 但是,如果您调用
g
,它将仍然alert
第一个参数。 What's happening? 发生了什么? Shouldn't calling
g
result in a stack overflow? 调用
g
不应该导致堆栈溢出吗?
What I understand is that inside the function f
(now g
) the variable f
is no longer bound to f
. 据我了解,在函数
f
(现在为g
)中,变量f
不再绑定到f
。 It becomes a free variable. 它成为一个自由变量。 Hence inside
f
the variable f
now points to alert
. 因此,在
f
内部,变量f
现在指向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.
我只是好奇。
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
. 但是,由于您已重新分配
f
因此它不再指向原始功能,因此现在指向alert
。 Looks like it's working as designed. 看起来它正在按设计工作。
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. 也就是说,
f
的值不是在声明时解析的,而是在函数调用期间解析的。 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. f
的值在声明中受约束,并且不受重新分配的影响。 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. 在命名函数表达式中,函数名称仅在表达式内部定义,因此其行为更像是闭包而不是变量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.