'return'关键字是什么类型的?

时间:2016-04-18 09:55:31

标签: javascript return keyword

我们在JavaScript函数中可以选择使用return语句。这是一个关键字。但是return本身的实际类型是什么。实际上我很困惑,看到了这个例子:

function add(a, b) {
  return (
    console.log(a + b),
    console.log(arguments)
  );
}

add(2, 2);

输出:

4
[2, 2]

因此,我们可以将逗号分隔的表达式传递给return语句。这是一个功能吗?

从这开始,我们可以猜测JavaScript中的每个关键字最终都是一个函数吗?

我写了一篇小博客作为讨论的要点。您可能需要检查here

6 个答案:

答案 0 :(得分:129)

  

但是'返回'的实际类型是什么?本身。

它没有类型,它不是一个值。

尝试typeof return;会给你Unexpected token return

  

因此,我们可以将逗号分隔的表达式传递给return语句。这是一个功能吗?

不,虽然括号可以用于调用函数,但这里它们是grouping operator,其中包含由comma operator分隔的几个表达式。

更有用的演示将是:

function add(a, b) {
  return (
    (a + b),
    (a - b)
  );
}

console.log(add(2, 2));

哪个输出0,因为a + b的结果被忽略(它位于逗号运算符的LHS上)并返回a - b

答案 1 :(得分:32)

我有点震惊,这里没有人直接引用the spec

  

12.9返回语句语法ReturnStatement:return;返回[此处没有LineTerminator]表达式;

     

<强>语义

     

ECMAScript程序在语法上被认为是不正确的   包含不在FunctionBody中的return语句。一个   return语句导致函数停止执行并返回a   对来电者的价值。如果省略Expression,则返回值为   未定义。否则,返回值是Expression的值。

     

对ReturnStatement的评估如下:

     

如果表达式不存在,请返回(return, undefined, empty)。   让exprRef成为评估Expression的结果。   返回(return, GetValue(exprRef), empty)

因此,由于规范,您的示例为:

return ( GetValue(exprRef) )

,其中 exprRef = console.log(a + b), console.log(arguments)

根据spec on the comma operator ......

  

<强>语义

     

制作表达式:表达式,AssignmentExpression是   评估如下:

Let lref be the result of evaluating Expression.
Call GetValue(lref).
Let rref be the result of evaluating AssignmentExpression.
Return GetValue(rref).

...意味着每个表达式都将被评估,直到逗号列表中的最后一项,这将成为赋值表达式。所以你的代码return (console.log(a + b) , console.log(arguments))将会

1。)打印a + b

的结果

2。)没有什么可以执行,所以执行下一个表达式

3。)打印arguments,因为console.log()没有指定 退货声明

4.。)评估为未定义

5.)然后将其返回给调用者。

所以正确的答案是,return没有类型,它只返回某个表达式的结果。

下一个问题:

  

因此,我们可以将逗号分隔的表达式传递给return语句。   这是一个功能吗?

没有。 JavaScript中的逗号是一个运算符,定义为允许您将多个表达式组合成一行,并由规范定义,以返回列表中最后一个的计算表达式。

你还是不相信我?

<script>
alert(foo());
function foo(){
    var foo = undefined + undefined;
    console.log(foo);
    return undefined, console.log(1), 4;
}
</script>

使用该代码here播放并混淆列表中的最后一个值。它将始终返回列表中的最后一个值,在您的情况下恰好是undefined.

对于你的最后一个问题,

  

从这开始,我们可以猜测每个关键字   JavaScript最终是一个函数吗?

再一次,没有。语言Functions have a very specific definition。我不会在这里重印,因为这个答案已经变得非常长了。

答案 2 :(得分:15)

测试返回括号内容时会发生什么:

function foo() {
    return (1, 2);
}

console.log(foo());

给出答案2,因此看起来以逗号分隔的值列表会计算出列表中的最后一个元素。

实际上,括号在这里是无关紧要的,它们是分组操作而不是表示函数调用。但是,令人惊讶的是,逗号在这里是合法的。我在这里找到了一篇关于逗号如何处理的有趣博客文章:

https://javascriptweblog.wordpress.com/2011/04/04/the-javascript-comma-operator/

答案 3 :(得分:9)

return不是一个功能。它是发生它的函数的 continuation

考虑语句alert (2 * foo(bar));,其中foo是函数的名称。当您对其进行评估时,您会发现必须暂时搁置该语句的其余部分,以便集中精力评估foo(bar)。您可以将您预留的部分可视化为alert (2 * _),并填充空白。当您知道foo(bar)的值是什么时,您可以再次选择它。

你预留的是电话foo(bar)延续

调用return为该延续提供值。

评估foo中的函数时,foo的其余部分等待该函数减少到某个值,然后foo再次获取。您仍有一个目标是评估foo(bar),它只是暂停了。

评估return内的foo时,foo的任何部分都不会等待值。 return并未降低到您使用它的foo内的值。相反,它会导致整个调用 foo(bar)减少到一个值,目标&#34;评估foo(bar)&#34;被视为完整和被吹走。

当您不熟悉编程时,人们通常不会告诉您有关延续的信息。他们认为它是一个高级主题,只是因为一些非常高级的东西,人们最终有延续。但事实是,每次调用函数时,你都会一直使用它们。

答案 4 :(得分:6)

return这里是一只红鲱鱼。也许有趣的是以下变化:

function add(a, b) {
  return (
    console.log(a + b),
    console.log(arguments)
  );
}

console.log(add(2, 2));

输出为最后一行

undefined

因为该函数实际上没有返回任何内容。 (它将返回第二个console.log的返回值(如果有的话)。

实际上,代码与

完全相同
function add(a, b) {
    console.log(a + b);
    console.log(arguments);
}

console.log(add(2, 2));

答案 5 :(得分:1)

理解return语句的一种有趣方式是通过void运算符 看看这段代码

var console = {
    log: function(s) {
      document.getElementById("console").innerHTML += s + "<br/>"
    }
}

function funReturnUndefined(x,y) {
   return ( void(x+y) );
}

function funReturnResult(x,y) {
   return ( (x+y) );
}

console.log( funReturnUndefined(2,3) );
console.log( funReturnResult(2,3) );
<div id="console" />

由于return语句接受一个[[expression]]参数并将其返回给堆栈上的调用者,即arguments.callee.caller,它将执行void(expression)然后返回{{ 1}}这是对void运算符的评估。