在 JavaScript 中使用块的返回值

问题描述 投票:0回答:2

在我测试过的许多浏览器上,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
的情况下使用块的结果值?我真的很喜欢这个功能:)

javascript syntax syntactic-sugar
2个回答
17
投票

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

Completion类型用于解释语句的行为 (

break
,
continue
,
return
throw
) 控制。完成类型的值是形式的三元组 (type, value, target), 其中 typenormal, break, continue, return, 或 throwvalue 是任何 ECMAScript 语言值或 empty,以及 target 是任何 ECMAScript 标识符或 empty.

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

因此,

eval()
评估已作为源文本传入的程序。该程序(与任何 JavaScript 程序一样)返回一个 Completion 值。此完成值中的第二项(“值”项)由
eval()
调用返回。

因此,使用

eval
您可以检索 JavaScript 程序的 completion value。我不知道有任何其他方法可以做到这一点......


7
投票

有人建议 ES7 引入一个 do 表达式 允许将任何块转换为表达式。一个 do 表达式计算一个块并返回它的完成值。

使用这种语法,您今天可以使用 Babel 使用 syntax-do-expressiontransform-do-expression 插件进行尝试,您的示例将如下所示:

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));
© www.soinside.com 2019 - 2024. All rights reserved.