我们在JavaScript函数中可以选择使用return语句。这是一个关键字。但是return
本身的实际类型是什么。实际上我很困惑,看到了这个例子:
function add(a, b) {
return (
console.log(a + b),
console.log(arguments)
);
}
add(2, 2);
输出:
4
[2, 2]
因此,我们可以将逗号分隔的表达式传递给return
语句。这是一个功能吗?
从这开始,我们可以猜测JavaScript中的每个关键字最终都是一个函数吗?
我写了一篇小博客作为讨论的要点。您可能需要检查here。
答案 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运算符的评估。