Использование возвращаемого значения блока в JavaScript - PullRequest
14 голосов
/ 23 декабря 2011

Во многих браузерах, которые я тестировал, блоки 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, который я пропускаю? Мне очень нравится эта функция:)

Ответы [ 2 ]

15 голосов
/ 23 декабря 2011

В JavaScript операторы возвращают значения типа Completion (который не является языковым типом, а типом спецификации).

Тип Completion используется для объяснения поведения операторов (break, continue, return и throw), которые выполняют нелокальные передачи управления.Значения типа Завершение являются тройками вида ( тип , значение , цель ), где тип является одним из нормальное , перерыв , продолжение , возврат или throw , значение - любое значение языка ECMAScriptили пусто и target - любой идентификатор ECMAScript или пусто .

Источник: http://es5.github.com/x8.html#x8.9

Таким образом, eval() оценивает программу, которая была передана в качестве исходного текста.Эта программа (как любая JavaScript-программа) возвращает значение Completion.Второй элемент в этом значении завершения (элемент «значение») возвращается вызовом eval().

Таким образом, с помощью eval вы можете получить значение завершения изпрограмма JavaScript.Я не знаю ни одного другого метода для достижения этой цели ...

5 голосов
/ 17 января 2016

ES7 предлагает ввести выражение do , которое позволяет превратить любой блок в выражение.Выражение do оценивает блок и возвращает его значение завершения.

Используя этот синтаксис, который вы можете попробовать сегодня с Babel, используя плагины syntax-do-expression и transform-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));
...