How can I feature-detect ES6 generators?
Asked Answered
T

2

13

I'm really enjoying ES6 generators. Is there a way I can detect generator support in browsers? I know generators might not be in a lot of browsers (or possible no browsers at all) at the moment, but that's OK for my purposes.

I tried:

try {
  function *(){}
} catch(err) {
  console.log("No generators");
}

But it doesn't seem to work.

How can I detect support for ES6 generators in browsers?

Terminator answered 15/4, 2014 at 23:0 Comment(2)
It's easy using eval, but how would it be useful to detect it?Philous
you can use the feature-detect-es6 library..Jonijonie
S
17

One of the few times that eval is actually the right solution.

For language construct changes, you need something like this:

try {
  eval("(function *(){})");
} catch(err) {
  console.log(err);
  console.log("No generators");
}
Seven answered 15/4, 2014 at 23:7 Comment(3)
Thanks @jeremy! I made a small change after testing this in Firefox (which currently supports generators). Just having a generator expression alone will 'SyntaxError: function statement requires a name', so I added an IIFE.Terminator
@Terminator I put things back in quotes. You do need that as a string for older browsers who don't support the syntax.Seven
No need to actually apply the generator in the eval string.Philous
C
5

Jeremy nicely explained how to test for generators support. You need to use eval:

isGeneratorSupported = function(){
    try {
       eval("(function*(){})()");
       return true;
    } catch(err){
       return false;
    }
}
alert( isGeneratorSupported() );

I will try to explain why your way does not work.

When you check whether some of JS/html5 features are supported and you use something like this:

function isCanvasSupported(){
  var elem = document.createElement('canvas');
  return !!(elem.getContext && elem.getContext('2d'));
}

JS engine parses you code, run it if it properly parsed and then compare the output to what you have expected and only because of this you function can tell that your feature is supported.

When you write the code like function *(){} JS engine fail on the very first step (parsing your code) and do not even try to execute it. This happens because * is not a new function, it is a new language construct and older versions of JS engine will just throw a syntaxError. The same way if you will write function f(x, ...y) {}, function f(x, y=1){} or even just ]. They all are invalid constructs in current JS (but 2 of them are valid in ES6, and who knows maybe ] will be valid in some ES10.)

The way to bypass it is ask your engine to somehow try to execute it. And by putting your code inside eval() you can do this.

Construct answered 26/7, 2014 at 0:37 Comment(1)
Then how can this be made to work if 'unsafe-eval' is prohibited by Content Security Policy, such as in Accelerated Mobile Pages?Wrought

© 2022 - 2024 — McMap. All rights reserved.