使用块';JavaScript中的s返回值

使用块';JavaScript中的s返回值,javascript,syntax,syntactic-sugar,Javascript,Syntax,Syntactic Sugar,在我测试过的许多浏览器上,JavaScript块实际上返回一个值。您可以在任何控制台中进行测试: for(var i = 0; i < 10; i++) { var sqrt = Math.sqrt(i); if(Math.floor(sqrt) === sqrt) { i; } } 但是如果eval是唯一的解决方案,我显然不想使用它。有没有一种方法可以在不使用我缺少的eval的情况下使用块的结果值?我非常喜欢这个特性:)在JavaScript中,

在我测试过的许多浏览器上,JavaScript块实际上返回一个值。您可以在任何控制台中进行测试:

for(var i = 0; i < 10; i++) {
    var sqrt = Math.sqrt(i);
    if(Math.floor(sqrt) === sqrt) {
        i;
    }
}

但是如果
eval
是唯一的解决方案,我显然不想使用它。有没有一种方法可以在不使用我缺少的
eval
的情况下使用块的结果值?我非常喜欢这个特性:)

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

完成类型用于解释语句的行为 (
break
continue
return
throw
)执行数据的非本地传输 控制完成类型的值是形式(类型, 值,目标),其中类型为正常中断继续返回, 或抛出,值为任何ECMAScript语言值或,且为目标 任何ECMAScript标识符或为空

资料来源:

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


因此,使用
eval
可以检索JavaScript程序的完成值。我不知道有任何其他方法可以实现这一点…

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

使用此语法(您今天可以使用和插件在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));
函数lastSquareNumber(val){
返回do{for(var i=0;i
块是语句,不是表达式。因此,您不能将它们用作操作数(不能对它们使用运算符)…您应该将
eval
的返回值视为异常,而不是JS“正常”(读取:忽略外部
eval
)施加的限制。块不是表达式。@ŠimeVidas:因为它很有趣。如果有一种很好的方法可以在任何JavaScript引擎中实现这一点,那么查看您可以添加的所有语法糖分将是一件很有趣的事情:)即使它不是用于生产目的。您确定您观察到的是块返回值,而不是控制台被设计为打印最后评估的内容吗?(这意味着控制台实际上是在打印最终的
i;
而不是您认为for循环返回的内容,假设实际上for循环不返回任何内容)。@minitech
eval()
返回作为源文本传入的JavaScript程序的完成值。这是一个有趣的观点。除此之外,我不知道还有任何其他方法可以接收程序/语句的完成值……我敢打赌,这种完成类型的东西只是用来指定一些原始的
eval
实现。@missingno我可以向您保证,完成类型是语言的一个重要部分。解释器使用完成值来确定执行中的下一步(即,将控制转移到调用方函数、跳转到迭代语句的开头等)。很抱歉,混淆了。除了eval之外,我想不出还有什么情况会关心完成值。(这个三元组中的第二个值,对于这个特定问题很重要)@hugomgthrow和return需要这些值,否则您希望如何“返回”一个值?可能eval是唯一关心普通类型完成中的值的东西。酷!我有点怀疑它是否能成功,但它也很好。这看起来很整洁,我希望它能在ES7中实现,但我想我们还得再等一段时间:)
eval('for(var i = 0; i < 10; i++) {var sqrt = Math.sqrt(i);if(Math.floor(sqrt) === sqrt) {i;}}') + 5; // 14
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));