2017-01-01 54 views
0

下面的代碼無法正常工作:JavaScript的結束 - 幫助我理解了爲什麼內部函數的返回值不返回

function addToAnswer(param){ 
    var answer = 10; 
    function adder(){ 
    return answer + param; 
    }; 
    adder(); 
} 
console.log(addToAnswer(5)); // returns undefined, expecting 15 

的修復這個代碼是return adder();我覺得很愚蠢,對我來說,addToAnswer()應返回的值從adder()功能。如果被問及爲什麼它不起作用,你會怎麼回答?

+2

'addToAnswer'沒有'return'語句,所以它返回'undefined'。 – Barmar

+0

注意:函數聲明最後不會使用';',''adder'函數聲明是多餘的(但是無害的)。 –

回答

2

如果問爲什麼它不起作用,你會怎麼回答?

我想說的是,在JavaScript中,函數一般不返回一個值,除非你明確使用return這樣做。 (有語言,特別是CoffeeScript,但不支持JavaScript。)

唯一的例外是簡明箭頭函數,它隱式返回它允許包含的一個表達式的結果。

這裏是正在使用簡潔的箭頭函數的例子:

someArray.sort((a, b) => a - b); 
//    ^^^^^^^^^^^^^^^---- concise arrow function 

但是,這是唯一的例外。詳細的箭頭功能,功能和方法都需要明確的return。如果通過函數獲取的代碼路徑沒有達到帶有值的明確return,則調用該函數的結果爲值undefined


(有些人可能認爲構造函數是第二個例外,因爲當你做new Thingy結果是新的啄即使Thingy沒有返回值,但它是不是真的在這種情況下,它是new表達有一個結果,而不是構造函數是隱式返回任何東西。而事實上,這種區分在規範中明確劃定。)

2

除非函數執行return聲明它會返回undefined。它不會自動返回函數中最後一行的值。所以,當你寫:

adder(); 

在函數結束時,它會調用adder(),返回15。然後addToAnswer丟棄該值並返回undefined

1

爲此,您需要了解退貨是如何工作的。

當你調用add();控件跳轉到add函數的開始處,當它到達return語句時,控件跳回到調用add函數的位置,以及處理後的任何值,並繼續處理其餘的代碼。由於addToAnswer函數沒有被告知返回一個值,因此它處理的代碼(計算參數+答案),但不返回任何東西,因此該函數的值是不確定的。

爲了進行實驗,您可以從內部函數中刪除return關鍵字,而不是return adder();。你會得到未定義的,因爲即使加法器函數處理了代碼,因爲它沒有明確要求返回值,但它沒有。

1

當函數adder()返回時,它只會彈出當前的執行上下文並返回到它下面的層 - addToAnswer()。您需要了解執行堆棧的工作原理:
1.首次運行文件時,將創建全局執行上下文。
2.未在另一個函數中定義的所有值都添加到全局執行上下文中。
3.當第一個函數運行時,會創建一個新的執行上下文。
4.這個新的執行上下文能夠引用在堆棧下面的任何父上下文中定義的變量和函數,在這種情況下是全局執行上下文。
5.最後,爲函數addToAnswer()中定義的任何函數彈出第三個執行上下文到堆棧。
enter image description here

http://davidshariff.com/blog/what-is-the-execution-context-in-javascript/ https://simpleprogrammer.com/2016/06/06/javascript-execution-stack-key-learning-language/