2016-03-02 49 views
0

以下代碼片段顯示一個基本對象,其中包含變量str,成員變量hello和成員函數test。我以爲我知道JS很好,並期望此代碼失敗,因爲test函數將被懸掛在頂部,並且將無法訪問strvm變量。然後我驚訝地發現這實際上起作用。爲什麼這個代碼的功能?起吊是否仍然發生?JS提升功能。 (爲什麼此代碼段工作?)

function SomeObject() { 
    var vm = this; 
    vm.hello = "hello"; 
    vm.test = test; 
    var str = "testig!"; 

    function test() { 
    console.log(vm.hello); 
    console.log(str); 
    } 
} 


var s = new SomeObject(); 

s.test(); 

輸出:

hello 
testig! 
+1

提升不影響範圍... – elclanrs

+0

總是發生提升 –

+1

爲什麼它無法訪問變量?它仍然在相同的範圍內。 – Bergi

回答

2

由於吊裝,你基本上結束了這一點:

function SomeObject() { 
    var vm; 
    var str; 
    var test; 
    test = function test() { 
    console.log(vm.hello); 
    console.log(str); // Works because we haven't run the function yet 
    } 

    vm = this; 
    vm.hello = 'hello'; 
    vm.test = test; 
    str = 'testig'; // str now has a value, function hasn't been called yet 
} 

var s = new SomeObject(); 
s.test(); // Function is called after str has been given a value 
+0

只有變量聲明被掛起。賦值'vm = this'不會移動到頂部。 (好的,由Bergi編輯修復) – Oriol

+0

@Bergi感謝您的快速解決。這在技術上是準確的,但我可以看到懸掛變量之前的函數如何仍然會令人困惑。從技術上講,他們同時存在,因爲第二次傳球,但在技術上仍然準確的時候很難顯示。 –

+2

我剛剛檢查了規範,它更像'var fm,str,test; test = function(){...}'。隨意將它移動到'var'聲明的下面,正如你所說的那樣無關緊要。 – Bergi

0

所有聲明都提升到其封閉範圍容器的頂部。

函數聲明,如:

function foo(){ } 

將被吊起到其封閉的範圍的頂部,因此它可以由被寫入前的功能代碼調用。

變量聲明也被掛起。所以,這樣的代碼:

var x = 10; 

將體驗提升爲好。但前一個例子中只有宣佈,所以只有

var x 

已被吊起。直到達到實際的代碼位置纔會發生x = 10分配。

類似地,函數表達式的工作方式也是一樣的。有了這個代碼:

var f = function() {}; 

只有var f懸掛,而不是分配。如果在實際代碼位置到達之前嘗試調用f,則會收到一個錯誤,指出f不是函數。

你的代碼的工作,只是因爲當你調用:

var s = new SomeObject(); 

,功能測試是不執行,但所有的變量賦值的。所以,當時間到了這個時候:

s.test(); 

所有的變量和函數都準備好了。

相關問題