que1326
que1326

Reputation: 2325

How try catch order is executed in JavaScript?

Given the test function, why the code from finally code is first executed rather then the one from the try block ? If so, the variable a has a new value of 5 ( from line 9 ) and then should have a new value of 8 ( from line 4 ). But it hasn't, the value of a is 6. Somehow only the logs are executed from finally block and assignments are ignored ? It's a bad practice to use return in try-catch blocks ? I see that in many popular frameworks the catch and finally blocks lack of return statement.

1    function test () {
2      window['a'] = 3; 
3      try {
4        window['a'] += 3;
5        return window['a'];
6      } 
7      catch(e) {} 
8      finally { 
9        window['a'] = 5;
10       console.log('finally');
11      }
12    }
13
14    console.log(test());

Snippet:

function test() {
  window['a'] = 3;
  try {
    window['a'] += 3;
    return window['a'];
  } catch (e) {} finally {
    window['a'] = 5;
    console.log('finally');
  }
}

console.log(test());

Output expected


6

finally

Execution output


finally

6

Upvotes: 1

Views: 1496

Answers (2)

curlyBraces
curlyBraces

Reputation: 1105

In the course of normal execution, the finally block is guaranteed to get executed after a try block. If an exception is thrown in the try block, then the order is try -> catch -> finally. In your code, even though we have a return statement as the last line in the try block, the finally block gets executed before exiting the method.

An example of when the finally block won't get executed is if the current thread is killed off while the try block is still running.


EDIT: From ECMAScript 2015 Language Specification section 13.15.8:

TryStatement : try Block Finally
Let B be the result of evaluating Block.
Let F be the result of evaluating Finally.
If F.[[type]] is normal, let F be B.
If F.[[type]] is return, or F.[[type]] is throw, return Completion(F).
If F.[[value]] is not empty, return Completion(F).
Return Completion{[[type]]: F.[[type]], [[value]]: undefined, [[target]]: F.[[target]]}.

Therefore, if a finally block executes normally, the result of try-finally block remains unchanged. This is why finally block should be used only for cleanup tasks and it should not contain any business logic.

Upvotes: 1

Mihai Ionut Ioan
Mihai Ionut Ioan

Reputation: 11

The execution order is TRY then CATCH then FINALLY (as usual).

You are returning the value in try block, so that why you have that output.

The try block is executed, then the finally one (because there are no errors), and it logs your message, then the function result is returned.

If you put console.log(window['a']) instead of return, you will see your expected output.

Upvotes: 1

Related Questions