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

Arn*_*Das 95 javascript return keyword

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

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

add(2, 2);
Run Code Online (Sandbox Code Playgroud)

输出:

4
[2, 2]
Run Code Online (Sandbox Code Playgroud)

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

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

我写了一篇小博客作为本次讨论的要点.你可能想在这里查看.

Que*_*tin 129

但是"回归"本身的实际类型是什么.

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

试图typeof return;会给你Unexpected token return.

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

不,虽然括号用于调用函数,但它们是一个分组运算符,包含由逗号运算符分隔的几个表达式.

更有用的演示将是:

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

console.log(add(2, 2));
Run Code Online (Sandbox Code Playgroud)

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

  • @ArnabDas - 是的.`a + b`只是没有可见的效果,因为它没有副作用,并且值被丢弃(好吧,鉴于它没有实际效果,优化编译器可能会删除它,但这没有实际区别) . (11认同)
  • @ArnabDas - 是的,它们被执行了,但是`return`没有看到它们,这就是你所要求的. (3认同)

avg*_*tvs 32

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

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

语义

如果ECMAScript程序包含不在FunctionBody中的return语句,则认为它在语法上是不正确的.return语句使函数停止执行并将值返回给调用者.如果省略Expression,则返回值未定义.否则,返回值是Expression的值.

ReturnStatement的计算方法如下:

如果表达式不存在,则返回(return, undefined, empty).让我们exprRef评估表达式的结果.返回(return, GetValue(exprRef), empty).

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

return ( GetValue(exprRef) )

哪里 exprRef = console.log(a + b), console.log(arguments)

根据逗号运算符规格 ...

语义

生产表达式:表达式,AssignmentExpression的评估如下:

Let lref be the result of evaluating Expression.
Call GetValue(lref).
Let rref be the result of evaluating AssignmentExpression.
Return GetValue(rref).
Run Code Online (Sandbox Code Playgroud)

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

1.)打印结果 a + b

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

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

4.)评估为undefined

5.)然后将其返回给呼叫者.

所以正确的答案是,return没有类型,它只返回一些表达式的结果.

对于下一个问题:

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

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

你还是不相信我?

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

在这里玩这个代码并弄乱列表中的最后一个值.它将始终返回列表中的最后一个值,在您的情况下它恰好是undefined.

对于你的最后一个问题

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

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


Spo*_*ser 15

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

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

console.log(foo());
Run Code Online (Sandbox Code Playgroud)

给出答案2,因此看起来以逗号分隔的值列表评估列表中的最后一个元素.

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

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


小智 9

return不是一个功能.这是它发生的功能的延续.

想想声明alert (2 * foo(bar));哪里foo是函数的名称.当你评估它时,你会发现你必须暂时搁置其余的陈述以集中精力进行评估foo(bar).您可以将您预留的部分想象成类似的东西alert (2 * _),填充空白.当您知道它的价值时foo(bar),您会再次拾起它.

你留出的东西是电话的延续foo(bar).

调用returnFeed为该延续提供值.

当您评估内部函数时foo,其余的foo等待该函数减少到一个值,然后foo再次拾取.你仍然有一个评估的目标foo(bar),它只是暂停.

当您评估return内部时foo,没有任何部分foo等待值.return不会减少到foo您使用它的地方的值.相反,它会导致整个调用 foo(bar)减少到一个值,并且目标"评估foo(bar)"被视为完成并被吹走.

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


ths*_*ths 6

return这里是一个红色的鲱鱼.也许有趣的是以下变化:

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

console.log(add(2, 2));
Run Code Online (Sandbox Code Playgroud)

哪个输出作为最后一行

undefined
Run Code Online (Sandbox Code Playgroud)

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

实际上,代码完全相同

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

console.log(add(2, 2));
Run Code Online (Sandbox Code Playgroud)