简体   繁体   English

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

[英]JavaScript Closure - help me understand why inner function's return value does not return

Following code does NOT work: 以下代码不起作用:

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

The fix to this code is return adder(); 该代码的解决方法是return adder(); I feel pretty stupid that to me, addToAnswer() should return the value from adder() function. 我感到很愚蠢,对我来说, addToAnswer()应该从adder()函数返回值。 How would you answer if asked why it doesn't work? 如果被问到为什么不起作用,您将如何回答?

How would you answer if asked why it doesn't work? 如果被问到为什么不起作用,您将如何回答?

I'd say that in JavaScript, functions generally don't return a value unless you explicitly use return to do so. 我想说的是,在JavaScript中,除非您明确使用return ,否则函数通常不返回值。 (There are languages where they do, notably CoffeeScript, but not JavaScript.) (它们可以使用多种语言,特别是CoffeeScript,而不是JavaScript。)

The only exception is the concise arrow function , which implicitly returns the result of the one expression it's allowed to contain. 唯一的例外是简洁箭头函数 ,该函数隐式返回允许包含的一个表达式的结果。

Here's an example of a concise arrow function being used: 这是使用简洁箭头功能的示例:

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

But that's the only exception. 但这是唯一的例外。 Verbose arrow functions, function functions, and methods all require an explicit return . 详细的箭头函数, function函数和方法都需要显式 return If the code path taken through the function doesn't reach an explicit return with a value, the result of calling the function is the value undefined . 如果通过函数采用的代码路径未到达带有值的显式return ,则调用函数的结果将是值undefined


(Some may argue that constructor functions are a second exception to the rule, because when you do new Thingy the result is the new thingy even if Thingy doesn't have a return value, but it's not true. In that case, it's the new expression that has a result, not that the constructor is returning anything implicitly. And in fact, the distinction is clearly drawn in the specification.) (有些人可能会认为构造函数是该规则的第二个例外,因为当您执行new Thingy ,即使Thingy没有返回值,结果也很新,但事实并非如此。在这种情况下,它是new表达式具有结果,而不是构造函数隐式返回任何东西。实际上,在规范中清楚地标明了这种区别。)

Unless a function executes a return statement, it returns undefined . 除非函数执行return语句,否则它将返回undefined It doesn't automatically return the value of the last line in the function. 它不会自动返回函数中最后一行的值。 So when you write: 所以当你写:

adder();

at the end of the function, it calls adder() , which returns 15 . 在函数的末尾,它将调用adder() ,该函数返回15 Then addToAnswer discards this value and returns undefined . 然后addToAnswer放弃该值并返回undefined

For that, you need to understand how return works. 为此,您需要了解退货的工作方式。

When you call the add(); 调用add()时; the control jumps to the start of the add function, and when inside it reaches the return statement, the control jumps back to the point where the add function was called, along with any value if processed, and continues with the rest of the code. 控件跳到add函数的开头,当它内部到达return语句时,控件跳回到调用add函数的点以及所有值(如果已处理),然后继续执行其余代码。

Since the addToAnswer function is not told to return a value, hence it processes the code( calculating param + answer), but doesn't return anything, hence the value of that function is undefined. 由于未告知addToAnswer函数返回值,因此它将处理代码(计算参数+答案),但不返回任何内容,因此该函数的值未定义。

For the sake of experimentation you can remove the return keyword from the inner function and instead return adder(); 为了实验起见,您可以从内部函数中删除return关键字,而是return adder(); . You'd get undefined, because even though the adder function processed the code since it was not asked explicitly to return a value, it didn't. 您将无法定义,因为即使加法器函数由于未明确要求其返回值而处理了代码,但也没有。

When the function adder() returns, it only pops out the current Execution Context and return to the layer beneath it -- addToAnswer() . 当函数adder()返回时,它仅弹出当前执行上下文并返回到其下一层– addToAnswer() You need to understand how the Execution Stack works: 您需要了解执行堆栈的工作原理:
1. When a file is first run, a Global Execution Context is created. 1.首次运行文件时,将创建一个全局执行上下文。
2. All of the values not defined within another function are added to the Global Execution Context. 2.在另一个函数中未定义的所有值都将添加到全局执行上下文中。
3. When the first function is run, a new execution context is created. 3.运行第一个函数时,将创建一个新的执行上下文。
4. This new execution context is capable of referencing the variables and functions defined in whatever parent context is below it in the stack, in this case, the Global Execution Context. 4.这个新的执行上下文能够引用在堆栈中位于其下方的任何父上下文(在本例中为“全局执行上下文”)中定义的变量和函数。
5. Finally, a third execution context is popped onto the stack for any functions defined within function addToAnswer() . 5.最后,对于在addToAnswer()函数中定义的任何函数,将第三个执行上下文弹出到堆栈上。
在此处输入图片说明

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM