2013-07-03 87 views
2
<script type="text/javascript"> 
function sayAlice() { 
    var sayAlert = function() { console.log(alice); } 
    var alice = 'Hello Alice'; 
    return sayAlert; 
} 
sayAlice()(); 
</script> 

在控制檯,它顯示Hello Alice試圖瞭解其中一些在JS與變量聲明碼

問:

var alice(變量聲明)是後var sayAlert,爲什麼它仍然顯示正確結果,不是像'未定義'?

回答

2

因爲在那個sayAlert實際執行(在sayAlice()()調用)的時候,Hello Alice已被分配到alice。由於JavaScript的關閉,alice在執行時可用於sayAlert

1

因爲saysAlert是一個函數, 它只是實現的,當您返回saysAlert其容納function和你宣佈alice後的事實。

這一個會給你一個未定義的變量:

<script type="text/javascript"> 
function sayAlice() { 
var sayAlert=''; 
console.log(alice); // alice is undefine up to this line 
var alice = 'Hello Alice'; 
return sayAlert; 
} 
sayAlice()(); 
</script> 

原代碼

<script type="text/javascript"> 
function sayAlice() { 
    var sayAlert = function() { console.log(alice); } // function sayAlert is not yet implemented 
    var alice = 'Hello Alice'; 
    return sayAlert; // function alert is implemented after the alice variable is define 
} 
sayAlice()(); 
</script> 
+1

因爲js沒有在程序上編譯 –

2

這是JavaScript範圍和提升機制。 看看this。由於吊裝,JavaScript的解釋你的腳本是這樣的:

<script type="text/javascript"> 
    function sayAlice() { 
     var alice; 
     var sayAlert = function() { console.log(alice); } 
     alice = 'Hello Alice'; 
     return sayAlert; 
    } 
    sayAlice()(); 
</script> 

var alice;var sayAlert = function() { console.log(alice); }申報前懸掛來。

+3

不是。它不需要提起。它與變量賦值後的內部函數執行*有關。 (提升僅解釋了爲什麼'var'的放置與變量*範圍*無關;爲什麼這個代碼輸出正確的行爲 - 特別是分配是*不移動*。) – Paul

+0

@KhanhTO在這一點上,'alice'首先在本地查找,然後在全局查詢(通過'window')並且不存在。這將是未定義的。 'sayAlert'不會在'sayAlice'返回之後執行,這就是爲什麼* sayAlice *有雙重執行(執行* sayAlice *然後* sayAlert *)的原因。因爲它仍然在範圍內,所以'alice'在那個時候被填充。 – vol7ron

1
<script type="text/javascript"> 
1: function sayAlice() { 
2:  var sayAlert = function() { console.log(alice); } 
3:  var alice = 'Hello Alice'; 
4:  return sayAlert; 
5: } 
6: sayAlice()(); 
</script> 
  • 線2被定義一個函數sayAlert,但不是要求/執行它。如果在結束大括號(})之後放置(),則日誌會打印undefined,因爲如您所述,alice直到之後纔會定義。

  • 4號線僅返回sayAlert功能,但同樣還沒有把它(注意它仍然不具備()

  • 線6接收先前從sayAlice()調用返回的功能,並增加了()呼叫返回的功能(sayAlert)。因此,在第6行運行sayAlice之後,它實際上看起來像sayAlert(),當它這樣做時,當調用console.log(...)時。 alice仍然暴露在範圍內,因爲它尚未被垃圾收集器銷燬(類似地如何關閉)工作。