在我测试过的很多浏览器中,JavaScript块实际上返回了一个值。您可以在任何控制台中测试它:
for(var i = 0; i < 10; i++) {
var sqrt = Math.sqrt(i);
if(Math.floor(sqrt) === sqrt) {
i;
}
}
“返回”值是最后一个方格数,即9!但是因为它不是我想的表达,你不能这样做:
for(var i = 0; i < 10; i++) {
...
} + 5
这不起作用。它当然会提供+ 5
或5
,因为它是一个单独的陈述。将循环放在括号中显然会失败,如果一个块在括号中(例如({f(); r})
- 不起作用),则将其视为对象并抛出语法错误。
利用返回值的一种方法是使用eval
:
eval('for(var i = 0; i < 10; i++) {var sqrt = Math.sqrt(i);if(Math.floor(sqrt) === sqrt) {i;}}') + 5; // 14
但如果eval
是唯一的解决方案,我显然不会想要使用它。有没有办法在不使用我遗漏的eval
的情况下使用块的结果值?我真的很喜欢这个功能:)
答案 0 :(得分:15)
在JavaScript中,语句返回Completion类型的值(不是语言类型,而是规范类型)。
Completion类型用于解释语句的行为 (
break
,continue
,return
和throw
)执行非本地转让 控制。 Completion类型的值是表单的三元组( type , 值,目标),其中类型是正常,中断之一,< strong>继续,返回, 或抛出,值是任何ECMAScript语言值或空,目标 是任何ECMAScript标识符或为空。
来源:http://es5.github.com/x8.html#x8.9
因此,eval()
评估作为源文本传入的程序。该程序(与任何JavaScript程序一样)返回Completion值。此完成值中的第二项(“值”项)由eval()
调用返回。
因此,使用eval
,您可以检索JavaScript程序的完成值。我不知道有任何其他方法可以实现这一目标......
答案 1 :(得分:5)
有人建议ES7引入do expression,允许任何块转换为表达式。 do表达式计算块并返回其完成值。
使用此语法,您今天可以使用syntax-do-expression和transform-do-expression插件与Babel一起试用,您的示例将如下所示:
function lastSquareNumber(val) {
return do { for(var i = 0; i < val; i++) {
var sqrt = Math.sqrt(i);
if(Math.floor(sqrt) === sqrt) {
i;
}
}}
}
console.log(lastSquareNumber(10));