I was preparing code samples for my ECMAScript 6 (ES6) workshop. ES6 has tons of new language features and programming in the next version of JavaScript is a lot of fun. In particular, ES6 supports block-level functions, so the following code should produce the error “doSomething is not defined”.
{ function doSomething(){ console.log("In doSomething"); } } doSomething();
And it does if you test it in ES6 Fiddle:
But the best part about ES6 is that you can use it today in your real world projects. Just run it through one of the transpilers, which will convert ES6 to ES5 code ready for deployment in all existing Web browsers. Let’s see how the Babel handles my block-level function:
As you can see, Babel renamed my function to _doSomething, so doSomething is not defined, which is correct.
The Traceur transpiler did pretty much the same trick, and doSomething is not defined:
Now let’s run the same code in the console of the developer’s edition of FireFox, which doesn’t support block-level functions. It behaves differently. Because of the hoisting, the declaration of the function doSomething has been moved to the top of the script and it is defined and works.
Google Chrome (allegedly supports block-level functions) also applies hoisting and invokes doSomething (stable and experimental JavaScript features were enabled). Something is broken here. After quick search I found this ES5 recommendation that in strict mode programmers shouldn’t declare functions in a statement context (ny statement they meant block). Let’s use strict mode and try it again in FireFox:
In strict mode this code gives a syntax error in FireFox. Chrome, Babel, and Traceur still produce “doSomething is undefined” in strict mode. It’s not the end of the world, but get prepared for inconsistent results.