1 回答

TA貢獻1833條經驗 獲得超4個贊
按照ECMAScript標準,函數表達式的樣式如下(opt記號代表的是可選的,也就是可有可無的意思):
FunctionExpression :function Identifier opt ( FormalParameterList opt ){ FunctionBody }
函式表達式中函數的識別名是可以不需要有的,有名稱的函數表達式,也就是所謂的"具名函數表達式"(Named function expressions,NFE),這個函數的識別名,它的作用域是只能在函數的主體(FunctionBody)內部。原因當然它只是個原本就可有可無的"代理"函數名,真正的這函數識別名稱是被賦值的那個變量識別名。
正常情況下,你只能在函數表述式中的主體中使用這個"代理函數名",這也是符合標準的規定,如下面的例子:
var f = function foo(){ return typeof foo; };typeof foo; // "undefined"f(); // "function"
那么又為何要使用這個"代理函數名",不是可有可無的嗎?
因為這個名稱在調試時,可以明確地在呼叫堆疊中看到,如果是不加這名稱,也就是"匿名函數表達式"在調試時是看不準是呼叫什么的。這使得調試時多了一些便利,所以它會被用在這個情況下。
但在IE8之前的IE版本,它對待這個"代理函數名",可以像一般的函數聲明
一樣。因為以IE8來說,它里面的JS引擎并不是現在的標準ECMAScript規定,而是JScript 5.8。
IE8并沒有設計這個封閉作用域,來界定出函數表達式的作用域,而且,在IE8中認為這種有"具名函數表達式",相等于函數聲明
。而且IE8還會認為這兩個函數(被賦值的變量與這個代理名)是兩個不同的函數物件,例如下面的例子:
var f = function foo(){ return 23; } alert(f === foo); //false
以上的資料主要參考Named function expressions demystified與Function Declarations vs. Function Expressions
本篇答案是改編自我之前在這篇問答中的答案。
添加回答
舉報