什么types是“返回”关键字?

我们可以在JavaScript函数中使用return语句。 这是一个关键字。 但是什么是实际的return本身。 其实我感到困惑,看到这样的例子:

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

输出:

 4 [2, 2] 

所以,我们可以将逗号分隔的expression式传递给return语句。 这是一个function?

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

我已经写了一个小博客作为这个讨论的要点。 你可能想在这里检查。

但是什么是“回报”本身的实际types。

它没有一个types,它不是一个值。

试图typeof return; 会给你Unexpected token return

所以,我们可以将逗号分隔的expression式传递给return语句。 这是一个function?

不,括号可以用来调用一个函数,在这里它们是一个分组操作符,包含一个由逗号分隔符分隔的几个expression式。

更有用的演示将是:

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

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

我有点震惊,没有人直接引用规范 :

12.9返回语句语法ReturnStatement:return; 返回[这里没有LineTerminator]expression式;

语义

如果ECMAScript程序包含不在FunctionBody内的返回语句,则ECMAScript程序在语法上被认为是不正确的。 返回语句会导致函数停止执行并向调用者返回一个值。 如果Expression被省略,则返回值是未定义的。 否则,返回值就是Expression的值。

ReturnStatement评估如下:

如果Expression不存在,则返回(return, undefined, empty) 。 让exprRef是评估expression式的结果。 返回(return, GetValue(exprRef), empty)

所以,由于规范,你的例子是:

return ( GetValue(exprRef) )

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

根据逗号运算符的规格 …

语义

生产Expression:Expression,AssignmentExpression的计算方法如下:

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

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

1.)打印a + b的结果

2)什么也没有执行,所以执行下一个expression式

3.)打印arguments ,因为console.log()没有指定返回语句

4.)评估为未定义

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

所以正确答案是, return没有types,它只返回一些expression式的结果。

对于下一个问题:

所以,我们可以将逗号分隔的expression式传递给return语句。 这是一个function?

不可以。JavaScript中的逗号是一个运算符,它定义为允许您将多个expression式组合到一行中,并由规范定义,以返回列表中最后一个元素的评估expression式。

你还不相信我?

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

在这里玩这个代码,搞乱列表中的最后一个值。 它总是会返回列表中的最后一个值,在你的情况下,它恰好是undefined.

对于你最后的问题,

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

再次,不。 函数在语言中有一个非常具体的定义 。 我不会在这里重印,因为这个答案已经非常长了。

testing返回括号值时会发生什么情况:

 function foo() { return (1, 2); } console.log(foo()); 

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

真的,括号在这里是不相关的,他们是分组操作,而不是表示函数调用。 但令人惊讶的是,逗号在这里是合法的。 我在这里find了一个有趣的博客文章:

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

return不是一个函数。 这是它发生的function的延续

考虑一下语句alert (2 * foo(bar)); 其中foo是函数的名称。 当你评估它的时候,你会发现你必须暂时搁置声明的其余部分,集中精力评估foo(bar) 。 你可以将你所预留的部分看作是alert (2 * _) ,并填上一个空格。当你知道foo(bar)的值是什么时,你再次拾取它。

你留下的东西是foo(bar)

调用return给这个延续提供一个值。

当你在foo里面计算一个函数时foo的其余部分等待这个函数减less到一个值,然后foo再次提取。 你仍然有一个目标来评估foo(bar) ,它只是暂停。

当你评价foo内部的returnfoo任何部分都不会等待一个值。 return值不会减less到你使用它的foo内部的某个值。 相反,它会导致整个调用 foo(bar)减less到一个值,并且“评估foo(bar) ”的目标被视为完整并被吹走。

当你不熟悉编程时,人们通常不会告诉你什么是延续。 他们认为这是一个先进的话题,只是因为人们最终了一些非常先进的事情。 但事实是,每当你调用一个函数,你就一直在使用它们。

这里的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)); 

理解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" />