Выразительный JavaScript.

Подчищаем за исключениями.

Представьте следующую ситуацию: функция withContext желает удостовериться, что во время её выполнения переменная верхнего уровня context содержит специальное значение контекста. В конце выполнения функция восстанавливает прежнее значение переменной.

Var context = null;

Function withContext(newContext, body) {

Var oldContext = context;

Context = newContext;

Var result = body();

Context = oldContext;

Return result;

}

Что, если функция body выбросит исключение? В таком случае вызов withContext будет выброшен исключением из стека, и переменной context никогда не будет возвращено первоначальное значение.

Но у инструкции try есть ещё одна особенность. За ней может следовать блок finally, либо вместо catch, либо вместе с catch. Блок finally означает «выполнить код в любом случае после выполнения блока try». Если функции надо что-то подчистить, то подчищающий код нужно включать в блок finally.

Function withContext(newContext, body) {

Var oldContext = context;

Context = newContext;

Try {

Return body();

} finally {

Context = oldContext;

}

}

Заметьте, что нам больше не нужно сохранять результат вызова body в отдельной переменной, чтобы вернуть его. Даже если мы возвращаемся из блока try, блок finally всё равно будет выполнен. Теперь мы можем безопасно сделать так:

Try {

WithContext(5, function() {

If (context < 10).

Throw new Error("Контекст слишком мал!");

});

} catch (e) {

Console.log("Игнорируем: " + e);

}

// → Игнорируем: Error: Контекст слишком мал!

Console.log(context);

// → null.

Несмотря на то, что вызываемая из withContext функция «сломалась», сам по себе withContext по-прежнему подчищает значение переменной context.