[英]Why does the function name inside a named function in JavaScript no longer refer to the function itself?
考慮以下命名函數:
function f() {
return f.apply(this, arguments);
}
如果正常調用此函數,則將導致堆棧溢出。 不太有趣。 因此,讓我們做一些魔術:
var g = f, f = alert;
現在,如果調用f
,它將僅alert
第一個參數。 但是,如果您調用g
,它將仍然alert
第一個參數。 發生了什么? 調用g
不應該導致堆棧溢出嗎?
據我了解,在函數f
(現在為g
)中,變量f
不再綁定到f
。 它成為一個自由變量。 因此,在f
內部,變量f
現在指向alert
。
為什么會這樣? 我希望命名函數中的函數名稱總是引用函數本身。 我沒有抱怨。 實際上很酷。 我只是好奇。
當您這樣做時:
var g = f
這實際上與以下內容相同:
var g = function () {
return f.apply(this, arguments);
}
但是,由於您已重新分配f
因此它不再指向原始功能,因此現在指向alert
。 看起來它正在按設計工作。
如其他答案所述,它是設計好的。 基本上,除了吊裝之外,聲明還這樣做:
var f = function () {
return f.apply(this, arguments);
}
也就是說, f
的值不是在聲明時解析的,而是在函數調用期間解析的。 這就是為什么您看到自己所看到的。
但是有一種方法可以強制其按照您想要的方式運行:使用命名函數表達式 。 命名函數表達式看起來像一個聲明,但不是由於該函數被聲明為表達式。
例如,在下面:
var ff = function f () {
return f.apply(this, arguments);
}
f
的值在聲明中受約束,並且不受重新分配的影響。 在命名函數表達式中,函數名稱僅在表達式內部定義,因此其行為更像是閉包而不是變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.