왜`finally`의 리턴이`try`보다 우선합니까?


98

try / catch 블록 내의 return 문은 어떻게 작동합니까?

function example() {
    try {
        return true;
    }
    finally {
        return false;
    }
}

이 함수의 출력이 될 것으로 예상하고 true있지만 대신 false!


다른 사람들의 경우 최종적으로가 아니라 catch 블록에서 false를 반환하십시오.
habibhassani

답변:


93

마지막으로 항상 실행됩니다. 그것은 그것이 당신의 경우에 사용된다는 것을 의미합니다.

코드를 다음과 같이 변경하고 싶을 것입니다.

function example() { 
    var returnState = false; // initialisation value is really up to the design
    try { 
        returnState = true; 
    } 
    catch {
        returnState = false;
    }
    finally { 
        return returnState; 
    } 
} 

일반적으로 함수에 하나 이상의 return 문을 갖고 싶지는 않습니다. 이런 이유가 있습니다.


45
하나 이상의 return 문을 갖는 것이 항상 나쁜 것은 아니라고 주장 합니다. 자세한 내용은 stackoverflow.com/questions/36707/… 을 참조하십시오 .
Castrohenge

5
나는 하나의 반환 규칙에 대해서도 동의하지 않습니다. 하지만 마지막으로 돌아와서는 안됩니다 (C #에서는 허용되지도 않습니다).
erikkallen 2010 년

@erikkallen-좋은 지적입니다. TCF 블록 외부로 반환하는 것이 가장 좋지만 예제 코드는 약간 강제됩니다. :)
annakata

1
@Castrohenge-그것은 어렵고 빠른 규칙은 아니지만 해당 스레드의 대부분의 copunter-examples는 꽤 인위적이며 내가 보는 유일한 유효한 경우는 "guard clause"(본질적으로 맨 위에있는 입력 데이터 확인 패턴)입니다. 함수 및 조건부 반환). 그것은 완벽하게 유효한 경우이지만 실제로 그러한 반환은 예외 여야합니다 (다시 어렵고 빠르지 않음).
annakata

1
실제로 IE6 및 IE7에서는 매우 심각한 브라우저 버그로 인해 모든 경우에 항상 실행되지는 않습니다. 특히 – 더 높은 수준의 try-catch로 둘러싸여 있지 않은 try-finally 블록에서 예외가 발생하면 finally 블록이 실행되지 않습니다. 다음은 jsfiddle.net/niallsmart/aFjKq 테스트 케이스 입니다 . 이 문제는 IE8에서 수정되었습니다.
Niall Smart

44

ECMA-262 (2009 년 12 월 5 일)에 따르면 96 페이지 :

생산 TryStatement : try Block Finally은 다음과 같이 평가됩니다.

  1. B를 Block 평가의 결과라고하자.
  2. F를 마지막으로 평가 한 결과라고합시다.
  3. F.type이 정상이면 B를 반환합니다.
  4. F를 반환합니다.

그리고 pp. 36에서 :

완료 타입 (명령문의 동작을 설명하는 데 사용되는 break, continue, returnthrow제어 비 로컬 전송을 수행). 완료 유형의 값이 형태의 트리플이다 (타입 값, 타겟) , 유형 중 하나 인 normal, break, continue, return, 또는 throw, 값이 임의 인 ECMAScript 언어 값 또는 빈이며, 타겟은 임의의 ECMAScript를 식별자 또는 빈이다.

그것은 그 분명 return false완료 유형을 설정합니다 마지막 으로 반환 유발 try ... finally4. 반환 F를 .


2
이 질문에 대한 모든 종류의 "기본적으로 정확하지만 다소 칙칙하고 명확하지 않은"답변을 읽은 후,이 질문은 실제로 이해가되었습니다. 핵심은 try + catch (반환 또는 던지기 또는 정상적인 흐름) 끝에서 "일어나는"모든 것이 finally 부분을 실행하는 동안 기억 된 다음 실제로 끝날 때 아무 일도 일어나지 않는 경우에만 발생한다는 것입니다.
PreventRage

14

를 사용 finally하면 메서드가 종료되기 전에 해당 블록 내의 모든 코드가 실행됩니다. finally블록 에서 리턴을 사용하기 때문에 블록 return false에서 이전 return true을 호출 하고 재정의합니다 try.

(용어가 정확하지 않을 수 있습니다.)


3

왜 당신이 거짓인지는 finally 블록에서 반환됩니다. finally 블록은 항상 실행되어야합니다. 그래서 당신의 return true변경return false

function example() {
    try {
        return true;
    }
    catch {
        return false;
    }
}

3

finally 블록은 try 블록 반환을 다시 작성합니다 (비상 적으로 말하면).

마지막으로 무언가를 반환하면 함수에서 반환된다는 점을 지적하고 싶었습니다. 그러나 마지막으로 'return'단어가 없으면 try 블록에서 값을 반환합니다.

function example() {
    try {
        return true;
    }
    finally {
       console.log('finally')
    }
}
console.log(example());
// -> finally
// -> true

그래서 return-finally-는 -try-의 반환을 다시 작성합니다 return.


1

내가 아는 한, finally블록 return 내부 에 문 이 있는지 여부에 관계없이 항상 실행 try됩니다. Ergo, 당신은return finally 블록 내부 문에서 .

우분투에서 Firefox 3.6.10과 Chrome 6.0.472.63으로 이것을 테스트했습니다. 이 코드는 다른 브라우저에서 다르게 작동 할 수 있습니다.


1

여기서 약간 다른 대답을하겠습니다. 예, tryfinally블록이 모두 실행되고 finally함수의 실제 "반환"값보다 우선합니다. 그러나 이러한 반환 값이 코드에서 항상 사용되는 것은 아닙니다.

그 이유는 다음과 같습니다.

  • 아래 예는 res.send() 는 HTTP 응답을 생성하고 디스패치하는 Express.js에서 합니다.
  • 귀하 tryfinally블록은 모두 다음 과 같이이 함수를 실행합니다.
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값을 함수 범위와 만 연관시키기 때문에 훈련되지 않은 눈으로이 사실을 난독 화합니다 .

Imho 최선의 방법은 블록 내부에서 사용하지 않는 것returnfinally 입니다. 코드가 지나치게 복잡해지고 잠재적으로 오류를 가릴 수 있습니다.

실제로 PHPStorm에는 이에 대한 "경고"를 제공하는 기본 코드 검사 규칙 설정이 있습니다.

https://www.jetbrains.com/help/phpstorm/javascript-and-typescript-return-inside-finally-block.html

그래서 당신은 무엇을 사용 finally합니까?

나는 finally물건을 청소 하는 데 에만 사용 합니다. 함수의 반환 값에 중요하지 않은 모든 것.

에서 코드 줄에 의존 할 때 또는에 finally오류가있을 수 있다고 가정하기 때문에 생각해 보면 이해할 수 있습니다 . 그러나 마지막 2 개는 오류 처리의 실제 구성 요소입니다. 그냥를 사용 으로 하고 대신.trycatchreturntrycatch


0

finally- 블록에서 복귀

는 IF finally- 블록은 값을 반환,이 값은 전체의 반환 값이됩니다 try-catch-finally어떤 관계없이 문을 return에서 문 trycatch-blocks

참조 : developer.mozilla.org


-2

마지막으로 try catch 블록의 끝에서 항상 실행되어 (사양에 따라) false가 반환되는 이유입니다. 브라우저마다 구현이 다를 수 있다는 점을 명심하십시오.


IE8, Firefox 3.6 및 Chrome 6 : 모두 동일 함;)
bonfo

-3

이건 어때?

doubleReturn();

function doubleReturn() {
  let sex = 'boy';

  try {
    return sex;

    console.log('this never gets called...');
  } catch (e) {} finally {
    sex = 'girl'; 

    alert(sex);
  }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.