为什么 JavaScript 函数总是返回一个值?

IT技术 javascript
2021-01-21 00:35:01

我正在学习 JavaScript 编程课程,讲师说典型的 JavaScript 函数总是返回一个值。即使我们不提供任何明确的返回值,引擎也会返回undefined.

真的吗?如果是这样,为什么?

4个回答

这是真的——因为 JavaScript 就是这样设计的。

但我不认为这就是您要寻找的答案,所以让我们考虑一下...
尝试将自己置于设计 JavaScript 的人Brendan Eich的角度!

静态语言中,不返回任何内容的void函数函数)和返回某个值的函数之间通常是有区别的Brendan 选择设计一种动态语言,即一种不需要您定义函数返回类型的语言。所以 JavaScript不会检查你从函数返回的内容,给你完全的自由。

你可以有一个返回一个数字的函数......

function computeSomething() {
  return 2;
}

...或字符串...

function computeSomething() {
  return 'hi';
}

......或者,事实上,其中任何一个:

function computeSomething() {
  if (Math.random() > 0.5) {
    return 2;
  } else {
    return 'hello';
  }
}

有时你不需要计算任何东西——你只需要做一些事情。
所以你什么都不返回。

function doSomething() {
   console.log('doing something');
}

然而,我们可能想要在它中间退出一个函数,并且因为return <value>已经这样做,所以允许在return没有值的情况下编写来支持这个用例是有意义的

function doSomething(num) {
   if (num === 42) {
     return;
   }

   while (true) {
     doSomethingElse();
   }
}

这也与 C/Java 语法一致,这是确保采用 JavaScript 的目标之一。

是的,有一个问题:如果我们将一个普通return的函数放入一个应该计算某些东西的函数中会发生什么?请注意,我们不能禁止这样做:我们之前的一个决定是让 JavaScript 成为一种动态语言,我们不检查函数返回的内容。

function computeSomething(num) {
  if (num === 42) {
    return; // just return? o_O
  }

  if (Math.random() > 0.5) {
    return 2;
  } else {
    return 'hello';
  }
}

var x = computeSomething(2); // might be 2, might be 'hello'
var y = computeSomething(42); // ???

当然,Brendan 可以决定在这种情况下提出错误,但他明智地决定不这样做,因为这会导致难以发现的错误和太容易破坏的代码。

所以空return的意思是“返回undefined”。

但是函数提前返回或结束返回有什么区别?从调用代码的角度来看,不应该有。调用代码不应该知道函数何时返回;它只对返回值(如果有)感兴趣。

因此,唯一合乎逻辑的结论是,undefined如果函数未通过显式return <value>运算符指定返回值,则使用“默认”返回值因此,return和函数执行到其端的语义匹配。

Python 是 JavaScript 之前出现的另一种动态语言,它以同样的方式解决了这个问题:None如果函数没有指定返回值,则返回

人们总是抱怨 JavaScript 的不好的部分——而且有很多——但是男孩,这门语言有太多的部分非常漂亮。
2021-03-24 00:35:01
很好的答案!您不仅要反省规范的一部分,还要分析此设计决策的含义和原因。
2021-03-29 00:35:01
“默认/未定义”值的想法通常作为语言中的概念很有用。一旦你引入了一个,你就可以做一些简单的事情,比如检查一个参数是否被传递(就像在 JS 中所做的那样),并且不从 void 函数返回 undefined 会很奇怪。
2021-04-06 00:35:01

这是ECMAScript 规范

13.2.1 [[Call]] ... 6. 否则 result.type 必须是正常的。返回未定义。

基本上任何 JS 函数都被编译为好像它return undefined;在最后有隐式一样

function foo() {
  ...

  return undefined; // implicit non-visible statement  
}

即使我们不提供任何明确的返回值,引擎也会返回“未定义”。真的吗?

并不真地。据我了解,一个什么都不返回的函数......什么都不返回。也就是说,如果您将变量分配给此类函数调用的结果,则表达式的计算结果为undefined

编辑

我站着纠正。这是规范的相关部分:


13.2.1 [[调用]]

当使用 this 值和参数列表调用 Function 对象 F 的 [[Call]] 内部方法时,将执行以下步骤:

  1. 令 funcCtx 成为使用 F 的 [[FormalParameters]] 内部属性的值、传递的参数 List args 和 this 值为函数代码建立新的执行上下文的结果,如 10.4.3 中所述。
  2. 令 result 是对 FunctionBody 求值的结果,FunctionBody 是 F 的 [[Code]] 内部属性的值。如果 F 没有 [[Code]] 内部属性或其值为空的 FunctionBody,则结果为(正常、未定义、空)。
  3. 退出执行上下文funcCtx,恢复之前的执行上下文。
  4. 如果 result.type 是 throw,则抛出 result.value。
  5. 如果返回 result.type,则返回 result.value。
  6. 否则 result.type 必须是正常的。返回未定义。
鼓起勇气改正错误,让所有人都看到。
2021-03-29 00:35:01
谢谢@Dan - 恐怕只有一些赞成票和一枚铜牌才能提供我所能提供的所有报酬:)
2021-04-03 00:35:01
“什么都不返回的函数......什么都不返回”是不正确的。JS 中没有“无”值。对于没有值的 return 语句,它“精确地返回 'undefined'”。参见:12.9 ECMA 规范中的 return 语句。
2021-04-14 00:35:01

在javascript中,函数是对象。因此,您始终可以将函数分配给变量,就像分配任何其他对象一样,解释器将强制确定一个值(可能未定义)。

这不是关于函数对象,而是关于函数调用。
2021-04-13 00:35:01