finally块总是最后执行,return语句将控制权返回到进行函数调用的位置。从try / finally块内部一起使用时,该函数似乎返回两次,而不是一次,如果在if-else块内部使用,则finally块的返回值生效。同一方法调用是否返回两次?
function print(value) {
console.log(value);
return value;
}
function testWrapped() {
try {
return print(true);
} finally {
return print(false);
}
}
function test() {
try {
return true;
} finally {
return false;
}
}
console.log("Result with wrapped value");
testWrapped();
console.log("Result when used inside an if statement:");
if (test()) {
console.log("true");
} else {
console.log("false");
}
上面的代码产生以下输出:
Result with wrapped value
true
false
Result when used inside an if statement:
false
答案 0 :(得分:4)
这是因为您使用的是finally
,而不是catch
最后将在尝试或捕获后执行。
在条件块中,它将返回上一个评估的项目false
,并执行else块。
请参阅:https://www.w3schools.com/jsref/jsref_try_catch.asp
try语句使您可以定义要测试的代码块 在执行时出现错误。
catch语句使您可以定义一个代码块 如果try块中发生错误,则执行。
finally语句使您可以在尝试捕获之后执行代码, 不管结果如何。
答案 1 :(得分:2)
两者都被评估,但实际上只有第二个被返回。
由于print()
的评估具有输出到控制台的副作用,因此可以看到评估。但是如果要使用console.log(testWrapped())
,则会在两个评估值之后看到返回的值。
您的代码等同于:
try {
result1 = print(true);
return result1;
}
finally {
result2 = print(false);
return result2;
}
希望这样可以使事情更清楚。
答案 2 :(得分:2)
深入了解它,spec说:
TryStatement :
try
最终阻止
- 让 B 成为评估 Block 的结果。
- 让 F 成为对 Finally 求值的结果。
- 如果 F 。[[type]]正常,则将 F 设为 B 。
- 如果返回 F 。[[type]],或者抛出 F 。[[type]],则返回Completion( F )。
- 如果 F 。[[value]]不为空,则返回Completion( F )。
- 完成返还{[[type]]: F 。[[type]],[[value]]:未定义,[[target]]:F。 [[target]]}。
将此应用于您的testWrapped()
代码,
try
块。 print(true)
的副作用会发生,因此true
将出现在控制台中。 try
块返回,因此求值结果是一个Completion,其类型为 return ,且值无论print(true)为:true 。 这还没有退回。 finally
块。同一件事:控制台中的false
,完成{[[type]]:返回,[[value]]: false }。finally
块的退货:false。最终结果:控制台中的true false
,并且testWrapped()
返回false。还有if
语句:
test
的{{1}}块:完成{[[type]]:返回,[[value]]: true }。try
的{{1}}块:完成{[[type]]:返回,[[value]]: false }。test
的完成返回:false。 finally
的值为finally
,并且执行test()
块。