在JavaScript中使用块的返回值

Ry-*_*Ry- 14 javascript syntax syntactic-sugar

在我测试过的很多浏览器中,JavaScript块实际上返回了一个值.您可以在任何控制台中测试它:

for(var i = 0; i < 10; i++) {
    var sqrt = Math.sqrt(i);
    if(Math.floor(sqrt) === sqrt) {
        i;
    }
}
Run Code Online (Sandbox Code Playgroud)

"返回"值是最后一个方格数,即9!但是因为它不是我想的表达,你不能这样做:

for(var i = 0; i < 10; i++) {
    ...
} + 5
Run Code Online (Sandbox Code Playgroud)

这不起作用.它给出了+ 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
Run Code Online (Sandbox Code Playgroud)

但我显然不会想要使用它,如果eval是唯一的解决方案.有没有办法在不使用eval我丢失的情况下使用块的结果值?我真的很喜欢这个功能:)

Šim*_*das 15

在JavaScript中,语句返回Completion类型的值(不是语言类型,而是规范类型).

完成类型用于解释语句的行为(break,continue,returnthrow)来实现控制的非局部传输.Completion类型的值是表单(类型, ,目标)的三元组,其中typenormal,break,continue,returnthrow之一,value是任何ECMAScript语言值或为,target 是任何ECMAScript标识符或者空的.

资料来源:http://es5.github.com/x8.html#x8.9

因此,eval()评估已作为源文本传入的程序.该程序(与任何JavaScript程序一样)返回Completion值.eval()调用返回此Completion值中的第二项("value"项).

因此,eval您可以检索JavaScript程序的完成值.我不知道有任何其他方法可以实现这一目标......


Rob*_*ght 5

ES7提议引入do表达式该表达式允许将任何块转换为表达式。do表达式计算一个块并返回其完成值。

使用此语法,您今天可以使用语法do-expressiontransform-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));
Run Code Online (Sandbox Code Playgroud)