Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
var str = 'class ಠ_ಠ extends Array {constructor(j = "a", ...c) {const q = (({u: e}) => {return { [`s${c}`]: Symbol(j) };})({});super(j, q, ...c);}}' +
'new Promise((f) => {const a = function* (){return "\u{20BB7}".match(/./u)[0].length === 2 || true;};for (let vre of a()) {' +
'const [uw, as, he, re] = [new Set(), new WeakSet(), new Map(), new WeakMap()];break;}f(new Proxy({}, {get: (han, h) => h in han ? han[h] ' +
': "42".repeat(0o10)}));}).then(bi => new ಠ_ಠ(bi.rd));';
try {
} catch(e) {
alert('Your browser does not support ES6!')
* All credits to Netflix for providing this approach to ES6 feature detection. Although this could be written in many different ways
* this proved to be the most direct and elegant approach for me.
* License: MIT
Copy link

DaBs commented Jan 20, 2017

Supports detection of following features:

  • Classes
  • Enhanced object literals
  • Template strings
  • Destructuring
  • Default + Rest + Spread
  • let + const
  • Iterators + for..of
  • Generators (function* ())
  • Unicode (ಠ_ಠ)
  • Proxies
  • Symbols
  • Subclassable built-ins
  • Promises
  • Arrows
  • New additions to APIs:

EDIT: As reddit user /u/Matthisk point out, this is NOT a fully featured feature detector, however if you're using some of the more advanced features we got in ES2015 that this script doesn't detect for, you probably already know that from reading it.

Copy link

CJX3M commented Jan 26, 2017

Love it!

Copy link

flying-sheep commented Jan 26, 2017


class ಠ_ಠ extends Array {
	constructor(j = "a", ...c) {
		const q = (({u: e}) => {
			return { [`s${c}`]: Symbol(j) }
		super(j, q, ...c)

new Promise((f) => {
	const a = function* () {
		return "\u{20BB7}".match(/./u)[0].length === 2 || true
	for (let vre of a()) {
		const [uw, as, he, re] = [new Set(), new WeakSet(), new Map(), new WeakMap()]
	f(new Proxy({}, {
		get: (han, h) => h in han ? han[h] : "42".repeat(0o10)
}).then(bi => new ಠ_ಠ(bi.rd))

Copy link

betaorbust commented Jan 28, 2017

Copy link

bevacqua commented Jan 31, 2017

Made it into a package: sixflix. Note: I minified the code in the original gist's str a bit, but the improvement is almost negligible:

class  extends Array{constructor(j=`a`,...c){const q=(({u: e})=>{return {[`${c}`]:Symbol(j)};})({});super(j,q,...c)}}new Promise(f=>{const a=function*(){return "\u{20BB7}".match(/./u)[0].length===2||!0};for (let z of a()){const [x,y,w,k]=[new Set(),new WeakSet(),new Map(), new WeakMap()];break}f(new Proxy({},{get:(h,i) =>i in h ?h[i]:"j".repeat(0o2)}))}).then(t => new (t.d))

Copy link

linuxenko commented Jan 31, 2017

Cool !

Copy link

mgenev commented Jan 31, 2017

does anyone know why nothing but transpilers support import/export? It's not not even in this list yet mdn lists it as a feature...

Copy link

mini-eggs commented Feb 1, 2017

@mgenev The how of implementing import/export has not been agreed upon.

Copy link

alextes commented Feb 1, 2017

@mgenev here's the short response from #node.js:

While ES6 provides syntax for import/export, it currently does nothing, anywhere, because the loader spec is not finished ( ). ES6 Modules are not yet a thing; they do not yet exist. !babel simply transpiles import/export to require, which is not guaranteed to work once the loader is finished. Use CommonJS modules for now.

Copy link

wintercounter commented Feb 1, 2017

Actually, it works in Safari TP.

Copy link

jokeyrhyme commented Feb 2, 2017

If you've got a decent CSP then eval() won't work. And unfortunately, eval() is the only way to safely test for syntax support. However, global APIs such as WeakMap can be safely tested without using eval().

Copy link

GrosSacASac commented Jun 3, 2017

There is another way also, using 2 script tags

Copy link

CharlSteynberg commented Jun 21, 2018

Maybe useful

Here's something i put together for "good-enough" client-side feature detection using OP's pattern and comments in this gist.
This checks support for:

  • ES6
  • WebGL
  • base64 btoa

.. (but wait there's more) :D

  • does not use eval
  • no extra script tag needed
  • works well with CSP
function playsNice(cb)
   var x='(function(){class ಠ extends Array{constructor(j=`a`,...c){const q=(({u:e})=>{return {[`${c}`]:Symbol(j)};})({});'+
   'super(j,q,...c)}}new Promise(f=>{const a=function*(){return "\u{20BB7}".match(/./u)[0].length===2||!0};for (let z of a())'+
   '{const [x,y,w,k]=[new Set(),new WeakSet(),new Map(),new WeakMap()];break}f(new Proxy({},{get:(h,i)=>i in h ?h[i]:"j".repeat'+
   '(0o2)}))}).then(t=>new ಠ(t.d)); if(!||!{throw "!"}; let n=document.createElement'+
   '("canvas"); let g=(!!n.getContext?(n.getContext("webgl")||n.getContext("experimental-webgl")):null); if(!g||!(g instanceof '+
   'WebGLRenderingContext)){throw "!"}; if(btoa("jz\'")!=="anon"){throw "!"};})();';

   if(!window.addEventListener){cb(false)}; var n=document.createElement('script'); n.ondone=function(event,s)
      s=this; if(s.done){window.removeEventListener('error',s.ondone,true); if(s.parentNode){s.parentNode.removeChild(s)}; return};
      this.done=1; cb(((event&&event.error)?false:true));

   window.addEventListener('error',n.ondone,true); n.appendChild(document.createTextNode(x));
   document.head.appendChild(n); setTimeout(n.ondone,50);


Copy link

vagdwd commented Mar 8, 2019

How would work unless CSP script-src 'unsafe-inline' is added?

Copy link

ItalyPaleAle commented Dec 5, 2019

Found an issue. Need to replace




Otherwise that is parsed outside of the eval and it will cause failures with things like UglifyJS that expects ES5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment