webmaster:
Here is a link to the ECMAScript specification. It seems that the return value of the finally block should always be ignored, unless it's "non-normal" - which means an exception, break, return statement or similar.
Some Tests
- Source: try{ "try" } finally { "finally" }
Result:- The specification says this should return "try".
- In Firefox 18 and 18.0.2, we see "finally"
- In node.js 0.16.19 and Chromium 23.0.1271.97, we see "finally"
- In IE 10.0.9200.16466 on and Intel64, we see "finally"
- In Opera version 12.12.1707, we see "try"
- In Safari 6.0, we see "finally"
- Source: while(true) { try{ "try" ; break } finally { "finally" } }
Result:- The specification says this should return "try".
- In Firefox 18 and 18.0.2, we see "finally"
- In node.js 0.16.19 and Chromium 23.0.1271.97, we see "finally"
- In IE 10.0.9200.16466 on ARM and Intel64, we see "finally"
- In Opera version 12.12.1707, we see "try"
- In Safari 6.0, we see "try"
- Source: x = "loop" ; while(x=="loop") { x = "stop looping" ; try{"try" ; break} finally { "finally" } ; x = "done" }
Result:- The specification says this should return "try".
- In Firefox 18 and 18.0.2, we see "finally"
- In node.js 0.16.19 and Chromium 23.0.1271.97, we see "try"
- In IE 10.0.9200.16466 on ARM and Intel64, we see "finally"
- In Opera version 12.12.1707, we see "try"
- In Safari 6.0, we see "try"
- Source: x = "loop" ; while(x=="loop") { x = "stop looping" ; try{"try" ; break} finally { "finally" } ; x = "done" } ; x
Result:- The specification says this should return "stop looping".
- In Firefox 18 and 18.0.2, we see "stop looping".
- In node.js 0.16.19 and Chromium 23.0.1271.97, we see "stop looping".
- In IE 10.0.9200.16466 on ARM and Intel64, we see "stop looping"
- In Opera version 12.12.1707, we see "stop looping"
- In Safari 6.0, we see "stop looping"
- Source: while(true) { try{"try"} finally {"finally"; break} }
Result:- The specification says this should return "finally".
- In Firefox 18 and 18.0.2, we see "finally".
- In node.js 0.16.19 and Chromium 23.0.1271.97, we see "finally".
- In IE 10.0.9200.16466 on ARM and Intel64, we see "finally"
- In Opera version 12.12.1707, we see "try"
- In Safari 6.0, we see "finally"
- Source: while(true) { try{"try"} finally {break} }
Result:- The specification says this should return the empty value.
- In Firefox 18 and 18.0.2, we see "try".
- in node.js 0.16.19 and Chromium 23.0.1271.97, we see "try".
- In IE 10.0.9200.16466 on ARM and Intel64, we see "try"
- In Opera version 12.12.1707, we see "try"
- In Safari 6.0, we see "try"
- Source: x = "loop" ; while(x=="loop") { x = "stop looping" ; try{"try" ; break} finally { } ; x = "done" }
Result:- The specification says this should return "try".
- In Firefox 18 and 18.0.2, we see "try".
- In node.js 0.16.19 and Chromium 23.0.1271.97, we see "try"
- In IE 10.0.9200.16466 on ARM and Intel64, we see "try"
- In Opera version 12.12.1707, we see "try"
- In Safari 6.0, we see "try"
- Source: x = "loop" ; while(x=="loop") { x = "stop looping" ; try{"try" ; break} finally { if(4){} } ; x = "done" }
Result:- The specification says this should return "try".
- In Firefox 18 and 18.0.2, we see "try".
- In node.js 0.16.19 and Chromium 23.0.1271.97, we see "try"
- In IE 10.0.9200.16466 on ARM and Intel64, we see "try"
- In Opera version 12.12.1707, we see "try"
- In Safari 6.0, we see "try"
- Source: try{throw "exception"}catch(e){ "catch" } finally { "finally" }
Result:- The specification says this should return "catch".
- In Firefox 18 and 18.0.2, we see "finally"
- In node.js 0.16.19 and Chromium 23.0.1271.97, we see "finally"
- In IE 10.0.9200.16466 on and Intel64, we see "finally"
- In Opera version 12.12.1707, we see "catch"
- In Safari 6.0, we see "finally"
- Source: while(true) { try{throw "exception"}catch(e){ "catch" ; break } finally { "finally" } }
Result:- The specification says this should return "catch".
- In Firefox 18 and 18.0.2, we see "finally"
- In node.js 0.16.19 and Chromium 23.0.1271.97, we see "finally"
- In IE 10.0.9200.16466 on ARM and Intel64, we see "finally"
- In Opera version 12.12.1707, we see "catch"
- In Safari 6.0, we see "catch"
- Source: x = "loop" ; while(x=="loop") { x = "stop looping" ; try{throw "exception"}catch(e){"catch" ; break} finally { "finally" } ; x = "done" }
Result:- The specification says this should return "catch".
- In Firefox 18 and 18.0.2, we see "finally"
- In node.js 0.16.19 and Chromium 23.0.1271.97, we see "catch"
- In IE 10.0.9200.16466 on ARM and Intel64, we see "finally"
- In Opera version 12.12.1707, we see "catch"
- In Safari 6.0, we see "catch"
- Source: x = "loop" ; while(x=="loop") { x = "stop looping" ; try{throw "exception"}catch(e){"catch" ; break} finally { "finally" } ; x = "done" } ; x
Result:- The specification says this should return "stop looping".
- In Firefox 18 and 18.0.2, we see "stop looping".
- In node.js 0.16.19 and Chromium 23.0.1271.97, we see "stop looping".
- In IE 10.0.9200.16466 on ARM and Intel64, we see "stop looping"
- In Opera version 12.12.1707, we see "stop looping"
- In Safari 6.0, we see "stop looping"
- Source: while(true) { try{throw "exception"}catch(e){"catch"} finally {"finally"; break} }
Result:- The specification says this should return "finally".
- In Firefox 18 and 18.0.2, we see "finally".
- In node.js 0.16.19 and Chromium 23.0.1271.97, we see "finally".
- In IE 10.0.9200.16466 on ARM and Intel64, we see "finally"
- In Opera version 12.12.1707, we see "catch"
- In Safari 6.0, we see "finally"
- Source: while(true) { try{throw "exception"}catch(e){"catch"} finally {break} }
Result:- The specification says this should return the empty value.
- In Firefox 18 and 18.0.2, we see "catch".
- in node.js 0.16.19 and Chromium 23.0.1271.97, we see "catch".
- In IE 10.0.9200.16466 on ARM and Intel64, we see "catch"
- In Opera version 12.12.1707, we see "catch"
- In Safari 6.0, we see "catch"
- Source: x = "loop" ; while(x=="loop") { x = "stop looping" ; try{throw "exception"}catch(e){"catch" ; break} finally { } ; x = "done" }
Result:- The specification says this should return "catch".
- In Firefox 18 and 18.0.2, we see "catch".
- In node.js 0.16.19 and Chromium 23.0.1271.97, we see "catch"
- In IE 10.0.9200.16466 on ARM and Intel64, we see "catch"
- In Opera version 12.12.1707, we see "catch"
- In Safari 6.0, we see "catch"
- Source: x = "loop" ; while(x=="loop") { x = "stop looping" ; try{throw "exception"}catch(e){"catch" ; break} finally { if(4){} } ; x = "done" }
Result:- The specification says this should return "catch".
- In Firefox 18 and 18.0.2, we see "catch".
- In node.js 0.16.19 and Chromium 23.0.1271.97, we see "catch"
- In IE 10.0.9200.16466 on ARM and Intel64, we see "catch"
- In Opera version 12.12.1707, we see "catch"
- In Safari 6.0, we see "catch"
Speculation about implementations
Spidermonkey (Firefox) and IE
Here is what we suspect Spidermonkey and IE are doing, when evaluating a block try { T } finally { F }
- Evaluate T and let (Tc,Tr) be the pair of its completion type and return value
- Evaluate F and let (Fc,Fr) be the pair of its completion type and return value
- If Fc is non-normal and Fr is empty, return (Fc,Tr)
- If Fc is non-normal and Fr is non-empty, return (Fc,Fr)
- If Fc is normal and Fr is empty, return (Tc,Tr)
- If Fc is normal and Fr is non-empty, return (Tc,Fr)
V8 (node.js and Chromium)
The difference in V8 behaviour between tests 2 and 3 is confusing. Here are some more tests, to explore this:
- Source: while(true) { try{ "try" ; break } finally { "finally" } }
Result:- In Chromium 23.0.1271.97, we see "finally"
- Source: while(true) { try{ "try" ; break } finally { "finally" } ; y = "done"}
Result:- In Chromium 23.0.1271.97, we see "try"
- Source: while(true) { try{ "try" ; break } finally { "finally" } ; if(true){2} else {3} }
Result:- In Chromium 23.0.1271.97, we see "try"
- Source: while(true) { try{ "try" ; break } finally { "finally" } ; if(true){2} else {var x = 3} }
Result:- In Chromium 23.0.1271.97, we see "finally"