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

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

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

这是真的,因为这就是JavaScript的devise原理。

但我不认为这是你正在寻找的答案,所以让我们来想一想…
试着把自己放在deviseJavaScript的人Brendan Eich的鞋子里!

静态语言中,通常不会返回任何东西的函数( void函数)和返回某个值的函数之间的区别。 Brendanselectdevise一种dynamic语言,即不要求你定义函数返回types的语言。 所以JavaScript 不检查你从函数返回的东西 ,给你充分的自由。

你可以有一个函数返回一个数字…

 function computeSomething() { return 2; } 

…或一个string…

 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成为一种dynamic语言,我们不检查函数返回的内容。

 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); // ??? 

当然布伦丹本可以决定在这种情况下提出一个错误,但是他明智地决定不这样做,因为这会导致难以发现的错误,并且很容易破坏代码。

所以一个空的return意味着“返回undefined ”。

但是函数返回的早期还是最后的区别是什么? 从调用代码的angular度来看,不应该有任何东西。 调用代码不应该知道函数何时返回; 它只对返回值感兴趣(如果有的话)。

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

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

这是ECMAScript规范

13.2.1 [[Call]] … 6.否则result.type必须正常。 返回undefined。

基本上任何JS函数编译,如果它有隐式return undefined; 最后:

 function foo() { ... return undefined; // implicit non-visible statement } 

即使我们没有提供任何显式的返回值,引擎也会返回“undefined”。 真的吗?

不是真的。 据我了解,一个函数不返回任何东西。 也就是说,如果你给这样一个函数调用的结果分配一个variables,那么这个expression式将被评估为undefined

编辑

我纠正了。 以下是规范的相关部分:


13.2.1 [[致电]]

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

  1. 假设funcCtx是使用F的[[FormalParameters]]内部属性的值,传递的参数List args和此值(如10.4.3中所述)为函数代码build立新的执行上下文的结果。
  2. 让结果成为评估F的[[Code]]内部属性值的FunctionBody的结果。 如果F没有[[Code]]内部属性,或者它的值是一个空的FunctionBody,则结果是(normal,undefined,empty)。
  3. 退出执行上下文funcCtx,恢复以前的执行上下文。
  4. 如果result.type是抛出然后扔result.value。
  5. 如果result.type返回,则返回result.value。
  6. 否则result.type必须是正常的。 返回undefined。

在JavaScript中,函数是对象。 因此,你总是可以将一个函数赋值给一个variables,就像分配任何其他对象一样,解释器将强制确定一个值(可能是未定义的)。