2014-04-16 53 views
1
吊裝的行爲
function myFunction() { 
    function myInternalFunction() { 
     return 10; 
    } 
    return myInternalFunction(); 
    function myInternalFunction() { 
     return 20; 
    } 
} 
alert(myFunction()); // What will this alert? 

答案是20不同的功能

function myFunction() { 
    var myInternalFunction = function() { 
     return "Hello World."; 
    } 
    return myInternalFunction(); 
    var myInternalFunction = function() { 
     return "Second Definition."; 
    } 
} 
alert(myFunction()); // What will this alert? 

答案是 「你好爾德」。

爲什麼?爲什麼不是「第二定義」?

+1

請參閱[var functionName = function(){} vs function functionName(){}](http://stackoverflow.com/q/336859/218196) –

+0

爲什麼?因爲在第一個例子中你使用的是函數**聲明**而在第二個例子中你使用的是函數**表達式**。 –

+1

關於您的編輯,這不等同於您之前的示例。你在第二次分配後調用'alert(a)'*,所以當然會提醒'two'。爲了使其等價於函數示例,您必須編寫'var a ='one'; alert(a)',var a ='two';'。 –

回答

3

變量的聲明懸掛,而不是它的定義。所以,你的第二個例子是等價於:

function myFunction() { 
    var myInternalFunction 
    myInternalFunction = function() { 
    return "Hello World." 
    } 
    return myInternalFunction() 

    myInternalFunction = function() { 
    return "Second Definition." 
    } 
} 

這裏,可以很明顯的是,myInternalFunction不可達,因此使用的第一個定義,因爲它是在myInternalFunction這就是所謂的時間價值。 JSLint的正確抱怨(使用原來的代碼):

無法到達varreturn後。


與你的第一個例子,其中函數聲明高掛比較,這樣你的代碼就相當於:

function myFunction() { 
    function myInternalFunction() { 
    return 10 
    } 
    function myInternalFunction() { 
    return 20 
    } 
    return myInternalFunction() 
} 

正如我們所看到的,myInternalFunction立即重新聲明,並所以最後一個勝利。在之前,兩個聲明都發生在之前。


那麼,爲什麼這種表情警惕最後叫變量:

var a = "one"; 
var a = "two"; 
alert(a); // alerts two ???? shouldn't be "one" if expressions? 

這並不等同於你的函數例子;一個等效的例子是:

var a = "one" 
alert(a) 
var a = "two" 

並期望它提醒「兩個」。我認爲這顯然不會。變量的值,無論是函數,字符串還是其他任何值都是不相關的。

+0

如果將函數(){}中的最後一個定義更改爲某個字符串,該怎麼辦? –

+0

@ C-link剛剛更新。 –

3

因爲,在第一種情況下,在編譯時本身,第二個myInternalFunction取代當前範圍中的第一個myInternalFunction。這意味着,myFunction的範圍中僅存在第二個myInternalFunction函數。

但在第二種情況下,函數僅在執行過程中創建。在執行alert時,只創建了第一個myInternalFunction函數,第二個myInternalFunction完全沒有創建。這就是爲什麼Hello World被警告。

+1

抱歉,無法正確理解。 –

+0

第二種情況使用了變量聲明。這意味着一旦代碼被執行,它就會被創建。但是你永遠不會執行那段代碼,因爲在這之前你有一個return語句。 在第一種情況下,您只需說明該範圍內存在哪些函數。 – superhero

0

函數聲明變量聲明總是移動(「懸掛」)不可見地其含有範圍由JavaScript解釋器的頂部。

注意它必須是函數聲明,這意味着只有function foo() {}的語法將被掛起。

一碼等於:

function myFunction() { 
    function myInternalFunction() { 
     return 10; 
    } 
    function myInternalFunction() { 
     return 20; 
    } 
    return myInternalFunction(); 
} 

二碼等於:

function myFunction() { 
    var myInternalFunction; 

    myInternalFunction = function() { 
     return "Hello World."; 
    } 

    return myInternalFunction(); 

    myInternalFunction = function() { 
     return "Second Definition."; 
    } 
} 
+0

根據你的回答我已經更新了我的問題。請檢查一下。 –

+1

@ C-link'var a =「one」; var a =「two」; '和'var a'一樣。 a ='one'; a ='two';',所以就是結果。 – xdazz