Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confirming ES5 support

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...).

like image 393
matanster Avatar asked Dec 12 '13 14:12

matanster


People also ask

What is ES5 compatible?

ES5 is fully supported in all modern browsers: Chrome. IE. Edge. Firefox.

What is meant by ES5?

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.

Is ES6 supported in all browsers 2021?

Browser SupportECMAScript 1 - 6 is fully supported in all modern browsers.

Do all browsers support ES6 now?

All the current browsers have full support to ES6.


2 Answers

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')
}
like image 193
Parris Avatar answered Oct 21 '22 09:10

Parris


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:

  1. Shim it.
  2. Test if it's supported before executing it and bail out if it's not.
  3. Let it fail (possibly using a crude global 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? :)

like image 18
kangax Avatar answered Oct 21 '22 10:10

kangax