2017-01-01 53 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/