JavaScript Closure - 帮助我理解为什么内部函数的返回值不会返回

时间:2017-01-01 09:34:42

标签: javascript closures

以下代码不起作用:

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

此代码的修复程序为return adder();我觉得非常愚蠢,addToAnswer()应该从adder()函数返回值。如果被问到为什么它不起作用,你会怎么回答?

4 个答案:

答案 0 :(得分:2)

  

如果被问到为什么它不起作用,你会如何回答?

我会说在JavaScript中,函数通常不返回值,除非显式地使用return这样做。 (他们有语言,特别是CoffeeScript,但不是JavaScript。)

唯一的例外是简明箭头函数,它隐式返回允许包含的一个表达式的结果。

以下是使用简明箭头函数的示例:

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

但这是唯一的例外。详细箭头函数,function函数和方法都需要显式 return。如果通过函数获取的代码路径未达到带有值的显式return,则调用该函数的结果为值undefined

(有些人可能认为构造函数是规则的第二个例外,因为当你执行new Thingy时结果就是新的东西,即使Thingy没有有一个返回值,但它不是真的。在这种情况下,它是 new表达式有一个结果,而不是构造函数隐式返回任何东西。事实上,区别是清楚地在规范中绘制。)

答案 1 :(得分:2)

除非函数执行return语句,否则返回undefined。它不会自动返回函数中最后一行的值。所以当你写:

adder();

在函数末尾,它调用adder(),返回15。然后addToAnswer会丢弃此值并返回undefined

答案 2 :(得分:1)

为此,您需要了解返回的工作原理。

当你调用add();控件跳转到add函数的开头,当它到达return语句时,控件跳回到调用add函数的位置,以及处理后的任何值,并继续执行其余的代码。

由于addToAnswer函数没有被告知返回一个值,因此它处理代码(计算param + answer),但不返回任何内容,因此该函数的值是未定义的。

为了实验,您可以从内部函数中删除return关键字,而不是return adder();。您未定义,因为即使加法器函数处理了代码,因为没有明确要求它返回值,它也没有。

答案 3 :(得分:1)

当函数cacerts返回时,它只会弹出当前的执行上下文并返回到它下面的层 - adder()。您需要了解执行堆栈的工作原理:
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/