Jak działa instrukcja return w bloku try / catch?
function example() {
try {
return true;
}
finally {
return false;
}
}
Oczekuję, że dane wyjściowe tej funkcji będą true
, ale zamiast tego jest false
!
Jak działa instrukcja return w bloku try / catch?
function example() {
try {
return true;
}
finally {
return false;
}
}
Oczekuję, że dane wyjściowe tej funkcji będą true
, ale zamiast tego jest false
!
Odpowiedzi:
Wreszcie zawsze wykonuje. Do tego służy, co oznacza, że zwrot jest używany w twoim przypadku.
Będziesz chciał zmienić swój kod, aby wyglądał bardziej tak:
function example() { var returnState = false; // initialisation value is really up to the design try { returnState = true; } catch { returnState = false; } finally { return returnState; } }
Ogólnie rzecz biorąc, nigdy nie chcesz mieć więcej niż jednej instrukcji return w funkcji, takie są przyczyny.
źródło
Według ECMA-262 (z dnia 5 grudnia 2009 r.), S. 96:
A ze strony 36:
To jasne, że
return false
byłoby ustawić typ zakończenia wreszcie jako zwrot , które powodujątry ... finally
zrobić 4. Zwrot F .źródło
Kiedy używasz
finally
, każdy kod w tym bloku jest uruchamiany przed zakończeniem metody. Ponieważ używasz powrotu wfinally
bloku, wywołuje onreturn false
i zastępuje poprzednireturn true
wtry
bloku.(Terminologia może nie być do końca poprawna).
źródło
Ostateczne przepisywanie bloku spróbuj powrotu bloku (mówiąc w przenośni).
Chciałem tylko zaznaczyć, że jeśli w końcu coś zwrócisz, to zostanie to zwrócone z funkcji. Ale jeśli w końcu nie ma słowa 'return' - zostanie zwrócona wartość z bloku try;
function example() { try { return true; } finally { console.log('finally') } } console.log(example()); // -> finally // -> true
Zatem
return
-w końcu- przepisuje zwrot z -try-return
.źródło
dlaczego otrzymujesz fałsz, czy wróciłeś w ostatnim bloku. ostatecznie blok powinien być wykonywany zawsze. więc twoje
return true
zmiany wreturn false
function example() { try { return true; } catch { return false; } }
źródło
O ile wiem,
finally
blok zawsze jest wykonywany, niezależnie od tego, czy wreturn
środku znajduje się instrukcja,try
czy nie. Ergo, otrzymujesz wartość zwróconą przezreturn
instrukcję wewnątrz końcowego bloku.Przetestowałem to w Firefoksie 3.6.10 i Chrome 6.0.472.63 w Ubuntu. Możliwe, że ten kod może zachowywać się inaczej w innych przeglądarkach.
źródło
Źródła: developer.mozilla.org
źródło
Podam tutaj nieco inną odpowiedź: Tak, zarówno blok , jak
try
ifinally
są wykonywane ifinally
mają pierwszeństwo przed rzeczywistą wartością „zwracaną” funkcji. Jednak te wartości zwracane nie zawsze są używane w kodzie.Dlatego:
res.send()
z Express.js, który tworzy odpowiedź HTTP i wysyła ją.try
ifinally
blok wykonają tę funkcję w następujący sposób:try { // Get DB records etc. return res.send('try'); } catch(e) { // log errors } finally { return res.send('finally'); }
Ten kod pokaże ciąg
try
w Twojej przeglądarce. TAKŻE przykład pokaże błąd w twojej konsoli.res.send()
Funkcja jest wywoływana dwukrotnie . Stanie się tak w przypadku wszystkiego, co jest funkcją. Blokada try-catch-last zaciemni ten fakt niewprawnym okiem, ponieważ (osobiście) kojarzę tylkoreturn
wartości z zakresami funkcji.Imho najlepiej jest nigdy nie używać
return
wewnątrzfinally
bloku . Zbyt mocno skomplikuje Twój kod i potencjalnie maskuje błędy.W rzeczywistości istnieje domyślna reguła inspekcji kodu ustawiona w PHPStorm, która daje „Ostrzeżenie” w tym przypadku:
https://www.jetbrains.com/help/phpstorm/javascript-and-typescript-return-inside-finally-block.html
Więc czego używasz
finally
?użyłbym
finally
tylko do porządkowania rzeczy. Wszystko, co nie jest krytyczne dla wartości zwracanej przez funkcję.Może to mieć sens, jeśli się nad tym zastanowisz, ponieważ gdy polegasz na wierszu kodu poniżej
finally
, zakładasz, że mogą wystąpić błędy wtry
lubcatch
. Ale te ostatnie 2 są faktycznymi elementami składowymi obsługi błędów. Po prostu użyjreturn
intry
icatch
zamiast.źródło
Ostatecznie powinien ZAWSZE działać na końcu bloku try catch, więc (zgodnie ze specyfikacją) jest powodem zwracania wartości false. Należy pamiętać, że jest całkowicie możliwe, że różne przeglądarki mają różne implementacje.
źródło
A co z tym?
doubleReturn(); function doubleReturn() { let sex = 'boy'; try { return sex; console.log('this never gets called...'); } catch (e) {} finally { sex = 'girl'; alert(sex); } }
źródło