我正在学习 JavaScript 编程课程,讲师说典型的 JavaScript 函数总是返回一个值。即使我们不提供任何明确的返回值,引擎也会返回undefined
.
真的吗?如果是这样,为什么?
我正在学习 JavaScript 编程课程,讲师说典型的 JavaScript 函数总是返回一个值。即使我们不提供任何明确的返回值,引擎也会返回undefined
.
真的吗?如果是这样,为什么?
这是真的——因为 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
如果函数没有指定返回值,则返回。
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]] 内部方法时,将执行以下步骤:
在javascript中,函数是对象。因此,您始终可以将函数分配给变量,就像分配任何其他对象一样,解释器将强制确定一个值(可能未定义)。