What are the best and simplest ways, in a Javascript (CoffeeScript) front-end application, to notify a user their browser is not supported, rather than letting it fail over unsupported ES5 features when they are randomly hit by the user? Say, I am writing something for only modern browsers, and I'd like to avoid a myriad of failures that old browsers would bump into wherever my code uses ES5-introduced features... by blocking non-compliant ES5 browsers?
ES5 introduced some syntax features, some of which I believe CoffeeScript relies on, and I would like my code to somehow avoid executing to begin with, if the browser does not support ES5, rather than tweaking shims, using Modernizr, or checking each CoffeeScript syntax subset to figure how backwards is it supported. Just ES5 and a clean "we're sorry your browser is too old" page for the rest of the world.
I do not wish to write code that tests every ES5 feature, nor necessarily rely on compliance tables such as http://kangax.github.io/es5-compat-table/ for checking the browser type and version (although, I would resort to the later, if no nicer alternatives...).
ES5 is fully supported in all modern browsers: Chrome. IE. Edge. Firefox.
ES5 is an abbreviation of ECMAScript 5 and also known as ECMAScript 2009. The sixth edition of the ECMAScript standard is ES6 or ECMAScript 6. It is also known as ECMAScript 2015. ES6 is a major enhancement in the JavaScript language that allows us to write programs for complex applications.
Browser SupportECMAScript 1 - 6 is fully supported in all modern browsers.
All the current browsers have full support to ES6.
I'm thinking about using the following try catch to test for some subset of es6.
In chrome right now this works:
try {
eval(`
'use strict';
class hello {
get hello() { return 123; }
}
`);
} catch(e) {
console.log('es6 classes are disabled :(')
}
Translating this to es5 to test for getters could look like:
try {
(function() {
eval('var dfojdfoj12 = { get hello() { return 123; } }');
})();
} catch(e) {
console.log('es5 getters do not exist')
}
There's no magic solution here.
For each ES5-only functionality (either it's Object.*
methods or String.prototype.*
methods or new syntax — getters, setters, etc.) you have 3 options:
try-catch
block).Why?
Because there's no such thing as "ES5" browser.
"ES5" is not a boolean value that could be evaluated. As you've seen from the compat. tables, ES5 is a pretty big set of features. And those features were implemented by different browsers/platforms in chunks, at various times, and with various compliance.
Of course you can always come up with some kind of clever inference test:
var isEngineES5Compliant = 'create' in Object &&
'isArray' in Array &&
'x'[0] === 'x';
But I'm sure you understand how brittle that is.
If a browser supports one method and you try to call another method — which might or might not be available — well, nothing good usually comes out of it. There will be false positives/negatives and there will be failures.
You say that you're writing only for modern browsers, but how exactly do you define a modern browser? Is it the one that supports ES5 fully? Or at least a subset of ES5 that your code is using? In that case you need to know exactly what subset that is.
Having said that, if we absolutely had to to come up with inference test to determine full ES5 compliance, I would go with:
(function () {
"use strict";
return Function.prototype.bind && !this;
}());
This checks support for "strict mode" (actually only part of strict mode but it will likely suffice) and presence of Function.prototype.bind
.
Both of these features were among the last to be implemented by browsers, so we're looking at IE10+, Firefox 4+, Safari 6+, Chrome 13+, and Opera 12+.
Note that even some of those browsers are not fully ES5-compliant (but that compliance is mostly about obscure-ish features).
Now, if you want truly modern browsers... how about testing for ES6 features? :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With