2014-11-05 72 views
0

Javascript有這個有趣的東西叫函數提升,這意味着我們可以使用函數表達式之前(即,視覺上)它被宣佈爲(謹慎:我的措辭可能不正確,隨時對其發表評論)當函數作爲參數傳遞時,Javascript函數提升不適用?

fn1(); // works OK 
function fn1() {console.log('fn1');} 

但是,如果我們傳遞一個命名函數作爲參數,函數提升不會發生。語法看起來很相似,但我想這不是一個函數表達式,而是一個命名的匿名函數(!)。

fn2(); // throws a ReferenceError as fn2 is not defined 
setTimeout(function fn2() {console.log('fn2')}, 0); 
  • 是它確實是一個函數表達式和一個名爲拉姆達之間的差異?
  • 兩者之間還有其他顯着差異嗎?
  • 考慮到fn2是一個命名的lambda,是否可以從fn2本身之外的任何地方訪問其名稱?
+0

@Sean我不認爲這是相同的問題:我不使用'var'在任何情況下,我的功能都在兩種情況下命名。我使用與該問題不同的完全相同的語法。 – Greg 2014-11-05 02:23:08

+1

就是這樣,你*不使用完全相同的語法。第一種情況是「函數聲明」(如果你願意的話,語法A),而第二種情況是「命名函數表達式」(語法B)。這兩種用於聲明函數的不同語法具有不同的行爲,如建議的重複問題和我在第一條評論中鏈接到的文章中所討論的。 – 2014-11-05 02:28:24

+1

by所指的「命名函數表達式」只是一個正常函數表達式。 * only *指定了一個「named」和一個「匿名」函數表達式(我知道)之間的區別是指定表達式的名稱在函數的作用域中可用。 – 2014-11-05 02:31:21

回答

1

唯一功能語句/聲明應綁定相應的變量(並有可能提升)。

參數列表中的setTimeout函數被視爲函數表達式;它有一個名稱(「fn2的」),但是不綁定到變量fn2和是之前創建的表達被評估 ..

+0

'理想',你的意思是它綁定到一些JS引擎上的變量fn2? – Greg 2014-11-05 02:25:21

+0

@Greg我已經編輯出來了。很久以前,在IE中,看起來像函數聲明的函數表達式(例如,在'if'中)將被視爲函數聲明。在反思中,我不相信這會影響表達式中的函數表達式。 – user2864740 2014-11-05 02:27:46

+1

函數聲明在大多數瀏覽器中不被支持,並且在那些函數聲明中不被「懸掛」。他們也不允許在嚴格模式下使用。 – RobG 2014-11-05 02:50:09

1

考慮fn2的是一個命名的λ,是可訪問的fn2的名稱從fn2本身以外的任何地方?

在越野車版本的IE中,是的。命名函數表達式在封閉執行上下文中被創建爲變量(與ECMA-262不一致)。見Named function expressions demystified