EcmaScript-6 backward compatibility

dopeddude picture dopeddude · May 10, 2015 · Viewed 9.7k times · Source

I am curious to understand/figure-out if the ECMAScript-6 new-changes will work on the old browsers or not.

Why I am asking this question is:

I remember the introduction of 'use strict'; in ECMAScript-5, it was meant for the compatibility with the old versions.

That means the old browsers will keep working fine and they will just ignore it when they encounter the 'use strict'; statement while parsing the new JavaScript code.

And the new JS-engines will treat the statement 'use strict'; in some special way as detailed here Strict mode.


So, coming to the question

I seriously doubt and curious to know how would the ECMAScript-5 compliant browsers behave when they will parse the ECMAScript-6 code.

The reason for my doubt is ECMAScript-6 new features involve syntax change/updates. And the old browsers which are new-syntax-unaware-engines will start throwing errors when they encounter any of the new syntax from the following

yield[*], Map, Set, WeakMap, function* foo(){}, =>, for...of etc.

My concern is has the decision/inclusion of new features in ECMAScript-6 taken care of supporting the old-browsers without any break of code?

If Yes then how?

If Not then what should I do to keep my old-browser-users happy?

I see one solution to keep the users using old browsers happy by including some transpiler like traceur-compiler in my project. This will convert my ECMAScript-6 code to ECMAScript-5 equivalent. But do I have any other solution to keep my old-browser-users happy?

Answer

jfriend00 picture jfriend00 · May 10, 2015

Many ES6 features will not work in an ES5 JS engine, particularly new syntax features such as for/of or arrow functions, generators, etc.... Some features like the Set object can be partially polyfilled for older browsers, others cannot.

Of the list of features you had in your question:

yield[*], Map, Set, WeakMap, function* foo(){}, =>, for...of

None of those are compatible with older versions of Javascript and will either cause syntax or reference errors. Some characteristics of Map and Set can be polyfilled (though not all). Yield, generators, arrow functions and for...of are just new syntax that older browsers do not process and cannot execute. It is possible to use an ES6 transpiler that will convert your code to ES5-compatible code. That isn't really ES6 backwards compatibility, but rather a code conversion that uses only ES5 syntax to accomplish the same things that are expressed in the newer ES6 syntax. Some of that is done with polyfills and some done with alternative ways of expressing an ES6 construct using only ES5 code (and usually more ES5 code).

If your code runs in something like node.js or if it's a plug-in for a specific version of a specific browser, then you have better control over the JS engine and can likely use ES6 features sooner than in a browser.

If your code runs in a browser and you're not using a transpiler to conver to ES5 code, then it will be awhile (many years) until most browsers in use on the internet are all ES6 ready.

The different purpose of "use strict"; (removing support for bad practices) is more consistent with allowing for compatibility with older versions than new language features like generators as the "use strict"; construct was specifically chosen to be something that a new browser could detect, but an older browser would just see as a normal string. New ES6 features that represent new language syntax are simply not that way as older browsers don't know how to process them and even if they could somehow ignore the newer syntax, they don't support the functionality that the new syntax implies.

You may find this article useful which discusses some of the issues in trying to use ES6 today:

ECMAScript 6 Resources For The Curious JavaScripter

If you want to use most of ES6 capabilities today in a wide range of browsers, then your best option is probably to transpile your code using something like BabelJS. This will transpile your ES6 code into ES5 compatible code that will run in any ES5 browser. You get to write in ES6, but the code will run in a wide range of browsers.

Or, if you're running in only a specific environment (such as a browser plug-in for a specific version of that browser) or a specific runtime engine such as node.js, then you can write code that uses the ES6 features that are already supported in that specific engine.