2017-04-20 67 views
4

我正在觀看JavaScript範圍的視頻,它表示在瀏覽器解釋java腳本代碼之前,它實際上涉及到一個快速編譯步驟(並不完全是「編譯」不涉及創建中間文件),它在各自的範圍內註冊變量和函數聲明。 所以,如果我寫:在Java腳本中註冊變量和函數聲明

var a = 3; 
function foo(){ 
var c = 2; 
} 

之前上面的表達式,這意味着忽略R.H.S.評估部分變量'a'和函數'foo'將在全局範圍內註冊並且在'foo'範圍內,變量'c'將被註冊。 完成這一編譯步驟後,表達式將被評估其值。

但是,當我們寫會發生什麼:

var a = function(){ 
var c; 
} 

將編譯步驟只是註冊變量「a」在全球範圍內,並跳過函數聲明和變量「c」的聲明,因爲編譯步驟應該跳過R.H.S.部分和評估表達式在解釋器部分?

+2

a仍然是一個全局函數,函數是匿名函數表達式,它將被評估位置,它不會像命名/聲明的函數那樣被提升,並且c仍然被註冊爲函數範圍的局部。 – zer00ne

回答

0

其實我後來想到了。它是吊裝的。吊裝僅適用於變量和函數聲明,不適用於函數表達式。 原來,函數表達式中唯一的時間函數以及它們的局部變量被註冊是java腳本解釋器運行時(編譯之後),因爲編譯步驟不會影響它們,因爲它們位於R.H.S部分。這確保了在函數表達式的情況下,我們只能在賦值之後調用它,解釋器負責在全局範圍內註冊的函數,並將其分配給L.H.S。變量及其局部變量的聲明(VAR巴):

var foo = function() { 
 
    console.log(bar); 
 
    var bar = 5; 
 
}; 
 
foo();

此功能對象被創建,只有當解釋器達到這一行:

var foo = function abc() { 

假如這一直是一個的情況下函數聲明,如下所示:

foo(); 
 

 
function foo() { 
 
    console.log(bar); 
 
    var bar = 5; 
 
}

提升會確保在編譯步驟中它註冊函數'foo'並在其範圍內聲明變量'bar'。

儘管如此,兩個程序都會給出相同的輸出 - 'undeifned'。