Как работает оператор return внутри блока try / catch?
function example() {
try {
return true;
}
finally {
return false;
}
}
Я ожидаю, что результат этой функции будет true
, но вместо этого он есть false
!
Ответы:
Наконец, всегда выполняется. Это то, для чего он нужен, а это значит, что в вашем случае используется return.
Вы захотите изменить свой код, чтобы он выглядел примерно так:
function example() {
var returnState = false; // initialisation value is really up to the design
try {
returnState = true;
}
catch {
returnState = false;
}
finally {
return returnState;
}
}
Вообще говоря, вы никогда не захотите иметь более одного оператора return в функции, вот почему.
Согласно ECMA-262 (5ed, декабрь 2009 г.), на стр. 96:
Производство
TryStatement : try Block Finally
оценивается следующим образом:
- Пусть B будет результатом вычисления Block.
- Пусть F будет результатом вычисления finally.
- Если F.type нормальный, верните B.
- Возврат F.
И со стр.36:
Тип Завершение используется для объяснения поведения операторов (
break
,continue
,return
иthrow
) , которые выполняют нелокальные передачу управления. Значения типа завершения являются триплеты вида (тип, значение, цель) , где тип является одним изnormal
,break
,continue
,return
, илиthrow
, значение любое значение ECMAScript языка или пустой, и целевой любой идентификатор ECMAScript или пуст.
Очевидно , что return false
бы установить тип завершения в конце концов , как возвращение , что вызывает try ... finally
делать 4. Возвращение F .
Перезапись блока finally пытается вернуть блок (образно говоря).
Просто хотел указать, что если вы вернете что-то из finally, то оно будет возвращено из функции. Но если в finally нет слова return - будет возвращено значение из блока try;
function example() {
try {
return true;
}
finally {
console.log('finally')
}
}
console.log(example());
// -> finally
// -> true
Итак, -finally- return
перезаписывает возврат -try- return
.
Насколько мне известно, finally
блок выполняется всегда , независимо от того, есть ли у вас return
внутри оператор try
или нет. Итак, вы получаете значение, возвращаемое return
оператором внутри блока finally.
Я тестировал это с Firefox 3.6.10 и Chrome 6.0.472.63 как в Ubuntu. Возможно, что этот код может вести себя иначе в других браузерах.
Возвращение из блока finally
Если
finally
-block возвращает значение, это значение становится возвращаемым значением всегоtry-catch-finally
оператора, независимо от любыхreturn
операторов вtry
иcatch
-blocks
Ссылка: developer.mozilla.org
Я дам здесь немного другой ответ: да, оба блока try
и finally
выполняются и finally
имеют приоритет над фактическим "возвращаемым" значением для функции. Однако эти возвращаемые значения не всегда используются в вашем коде.
Вот почему:
res.send()
файл из Express.js, который создает и отправляет HTTP-ответ.try
и finally
блок будет одновременно выполнять эту функцию следующим образом:try {
// Get DB records etc.
return res.send('try');
} catch(e) {
// log errors
} finally {
return res.send('finally');
}
Этот код покажет строку try
в вашем браузере. ТАКЖЕ, пример покажет ошибку в вашей консоли. res.send()
Функция вызывается дважды . Это произойдет со всем, что является функцией. Блок try-catch-finally скрывает этот факт от неподготовленного глаза, потому что (лично) я связываю return
значения только с областями действия.
Имхо, лучше всего никогда не использовать return
внутри finally
блока . Это усложнит ваш код и потенциально замаскирует ошибки.
Фактически, в PHPStorm есть настройка правила проверки кода по умолчанию, которая выдает «Предупреждение» для этого:
https://www.jetbrains.com/help/phpstorm/javascript-and-typescript-return-inside-finally-block.html
finally
?Я бы использовал finally
только для уборки вещей. Все, что не критично для возвращаемого значения функции.
Это может иметь смысл, если вы подумаете об этом, потому что, когда вы зависите от строки кода ниже finally
, вы предполагаете, что могут быть ошибки в try
или catch
. Но эти последние 2 - фактические строительные блоки обработки ошибок. Просто используйте вместо него return
in try
и catch
.
Как насчет этого?
doubleReturn();
function doubleReturn() {
let sex = 'boy';
try {
return sex;
console.log('this never gets called...');
} catch (e) {} finally {
sex = 'girl';
alert(sex);
}
}