UNPKG

caniuse-es-db

Version:

ECMAScript compatibility database based on kangax/compat-table

2,003 lines (1,993 loc) 284 kB
// exports browsers and tests Object.assign = require('object-assign'); var temp = {}; var flag = "flagged"; var strict = "strict"; var fallthrough = "needs-polyfill-or-native"; var typescript = { corejs: { val: true, note_id: "typescript-core-js", note_html: "This feature is supported when using TypeScript with core-js, or when a native ES6 host is used." }, fallthrough: { val: fallthrough, note_id: "typescript-es6", note_html: "TypeScript's compiler will accept code using this feature if the <code>--target ES6</code> flag is set, but passes it through unmodified and does not supply a runtime polyfill." } }; exports.name = 'ES6'; exports.target_file = 'es6/index.html'; exports.skeleton_file = 'es6/skeleton.html'; exports.browsers = { tr: { full: 'Traceur', short: 'Traceur', obsolete: false, platformtype: 'compiler', }, babel: { full: 'Babel', short: 'Babel +<br><nobr>core-js</nobr>', obsolete: false, platformtype: 'compiler', note_id: 'babel-optional', note_html: 'Flagged features require an optional transformer setting.', }, es6tr: { full: 'ES6 Transpiler', short: 'ES6<br>Trans-<br>piler', obsolete: true, platformtype: 'compiler', }, closure: { full: 'Closure Compiler v20150505', short: 'Closure', obsolete: false, platformtype: 'compiler', }, jsx: { full: 'JSX', short: 'JSX', obsolete: false, platformtype: 'compiler', note_id: 'jsx-flag', note_html: 'Have to be enabled via <code>harmony</code> option' }, typescript: { full: 'TypeScript 1.5-alpha', short: 'Type-<br />Script +<br /><nobr>core-js</nobr>', obsolete: false, platformtype: 'compiler' }, es6shim: { full: 'es6-shim', short: 'es6-<br>shim', obsolete: false, platformtype: 'compiler', }, ie10: { full: 'Internet Explorer', short: 'IE 10', obsolete: false // no EOL any time soon }, ie11: { full: 'Internet Explorer', short: 'IE 11', obsolete: false }, edge: { full: 'Internet Explorer, Microsoft Edge', short: 'Edge', unstable: true, note_id: 'edge-experimental-flag', note_html: 'Flagged features have to be enabled via "Enable experimental Javascript features" setting under about:flags' }, firefox11: { full: 'Firefox', short: 'FF 11-12', obsolete: true }, firefox13: { full: 'Firefox', short: 'FF 13', obsolete: true }, firefox16: { full: 'Firefox', short: 'FF 16', obsolete: true }, firefox17: { full: 'Firefox', short: 'FF 17', obsolete: true }, firefox18: { full: 'Firefox', short: 'FF 18', obsolete: true }, firefox23: { full: 'Firefox', short: 'FF 23', obsolete: true }, firefox24: { full: 'Firefox', short: 'FF 24', obsolete: true }, firefox25: { full: 'Firefox', short: 'FF 25', obsolete: true }, firefox27: { full: 'Firefox', short: 'FF 27', obsolete: true }, firefox28: { full: 'Firefox', short: 'FF 28', obsolete: true }, firefox29: { full: 'Firefox', short: 'FF 29', obsolete: true }, firefox30: { full: 'Firefox', short: 'FF 30', obsolete: true }, firefox31: { full: 'Firefox', short: 'FF 31<br>ESR', obsolete: false // ESR (EOL at Aug 2015) }, firefox32: { full: 'Firefox', short: 'FF 32', obsolete: true }, firefox33: { full: 'Firefox', short: 'FF 33', obsolete: true }, firefox34: { full: 'Firefox', short: 'FF 34', obsolete: true }, firefox35: { full: 'Firefox', short: 'FF 35', obsolete: true }, firefox36: { full: 'Firefox', short: 'FF 36', obsolete: true }, firefox37: { full: 'Firefox', short: 'FF 37', obsolete: true, }, firefox38: { full: 'Firefox', short: 'FF 38', obsolete: true, }, firefox39: { full: 'Firefox', short: 'FF 39', }, firefox40: { full: 'Firefox', short: 'FF 40', unstable: true, }, firefox41: { full: 'Firefox', short: 'FF 41', unstable: true, }, chrome: { full: 'Chrome', short: 'CH &lt;19', obsolete: true }, chrome19dev: { full: 'Chrome', short: 'CH 19', obsolete: true, note_id: 'experimental-flag', note_html: 'Flagged features have to be enabled via "Experimental Javascript features" flag' }, chrome21dev: { full: 'Chrome', short: 'CH 21-29', obsolete: true, note_id: 'experimental-flag', }, chrome30: { full: 'Chrome, Opera', short: 'CH&nbsp;30,<br>OP&nbsp;17', obsolete: true, note_id: 'experimental-flag', }, chrome31: { full: 'Chrome, Opera', short: 'CH&nbsp;31,<br>OP&nbsp;18', obsolete: true, note_id: 'experimental-flag', }, chrome33: { full: 'Chrome, Opera', short: 'CH&nbsp;32-33,<br>OP&nbsp;19-20', obsolete: true, note_id: 'experimental-flag', }, chrome34: { full: 'Chrome, Opera', short: 'CH&nbsp;34,<br>OP&nbsp;21', obsolete: true, note_id: 'experimental-flag', }, chrome35: { full: 'Chrome, Opera', short: 'CH&nbsp;35,<br>OP&nbsp;22', obsolete: true, note_id: 'experimental-flag', }, chrome36: { full: 'Chrome, Opera', short: 'CH&nbsp;36,<br>OP&nbsp;23', obsolete: true, note_id: 'experimental-flag', }, chrome37: { full: 'Chrome, Opera', short: 'CH&nbsp;37,<br>OP&nbsp;24', obsolete: true, note_id: 'experimental-flag', }, chrome38: { full: 'Chrome, Opera', short: 'CH&nbsp;38,<br>OP&nbsp;25', obsolete: true, note_id: 'experimental-flag', }, chrome39: { full: 'Chrome, Opera', short: 'CH 39,<br>OP&nbsp;26', obsolete: true, note_id: 'experimental-flag', }, chrome40: { full: 'Chrome, Opera', short: 'CH 40,<br>OP&nbsp;27', obsolete: true, note_id: 'experimental-flag', }, chrome41: { full: 'Chrome, Opera', short: 'CH 41,<br>OP&nbsp;28', obsolete: true, note_id: 'experimental-flag', }, chrome42: { full: 'Chrome, Opera', short: 'CH 42,<br>OP&nbsp;29', obsolete: true, note_id: 'experimental-flag', }, chrome43: { full: 'Chrome, Opera', short: 'CH 43,<br>OP&nbsp;30', obsolete: true, note_id: 'experimental-flag', }, chrome44: { full: 'Chrome, Opera', short: 'CH 44,<br>OP&nbsp;31', note_id: 'experimental-flag', }, chrome45: { full: 'Chrome, Opera', short: 'CH 45,<br>OP&nbsp;32', unstable: true, note_id: 'experimental-flag', }, chrome46: { full: 'Chrome, Opera', short: 'CH 46,<br>OP&nbsp;33', unstable: true, note_id: 'experimental-flag', }, safari51: { full: 'Safari', short: 'SF 5.1', obsolete: true }, safari6: { full: 'Safari', short: 'SF 6', obsolete: true }, safari7: { full: 'Safari', short: 'SF 6.1,<br>SF 7', obsolete: false }, safari71_8: { full: 'Safari', short: 'SF 7.1,<br>SF 8', obsolete: false }, webkit: { full: 'WebKit r185990', short: 'WK', unstable: true, }, opera: { full: 'Opera 12.16', short: 'OP 12', obsolete: true }, konq49: { full: 'Konqueror 4.14', short: 'KQ<br>4.14', note_id: 'khtml', note_html: 'Results are only applicable for the KHTML rendering engine.' }, rhino17: { full: 'Rhino 1.7', short: 'RH', platformtype: 'engine', obsolete: true, }, phantom: { full: 'PhantomJS 2.0', short: 'PJS', platformtype: 'engine', equals: 'safari6', // As PJS is a "headless browser" that emulates a real browser, it technically should support annex B. needs_annex_b: true, }, node: { full: 'Node 0.12.0', short: 'Node', platformtype: 'engine', note_id: 'harmony-flag', note_html: 'Flagged features have to be enabled via <code>--harmony</code> or <code>--es_staging</code> flag' }, iojs: { full: 'io.js 2.0.0', short: 'io.js', platformtype: 'engine', note_id: 'harmony-flag', }, ejs: { full: 'Echo JS', short: 'Echo JS', unstable: true, platformtype: 'engine', }, ios7: { full: 'iOS Safari', short: 'iOS7', platformtype: 'mobile', equals: 'safari7', }, ios8: { full: 'iOS Safari', short: 'iOS8', platformtype: 'mobile', equals: 'safari71_8', } }; exports.tests = [ { name: 'proper tail calls (tail call optimisation)', category: 'optimisation', significance: 'medium', link: 'http://www.ecma-international.org/ecma-262/6.0/#sec-tail-position-calls', subtests: { 'direct recursion': { exec: function() {/* "use strict"; return (function f(n){ if (n <= 0) { return "foo"; } return f(n - 1); }(1e6)) === "foo"; */}, res: { tr: { val: flag, note_id: 'tr-tco', note_html: 'Requires the <code>properTailCalls</code> compile option.' }, babel: true, typescript: typescript.fallthrough, }, }, 'mutual recursion': { exec: function() {/* "use strict"; function f(n){ if (n <= 0) { return "foo"; } return g(n - 1); } function g(n){ if (n <= 0) { return "bar"; } return f(n - 1); } return f(1e6) === "foo" && f(1e6+1) === "bar"; */}, res: { tr: { val: flag, note_id: 'tr-tco' }, typescript: typescript.fallthrough }, } } }, { name: 'arrow functions', category: 'functions', significance: 'large', link: 'http://www.ecma-international.org/ecma-262/6.0/#sec-arrow-function-definitions', subtests: { '0 parameters': { exec: function(){/* return (() => 5)() === 5; */}, res: { tr: true, babel: true, es6tr: true, jsx: true, typescript: true, ejs: true, closure: true, edge: true, firefox23: true, chrome38: flag, chrome40: false, chrome45: true, webkit: true, node: flag, }, }, '1 parameter, no brackets': { exec: function(){/* var b = x => x + "foo"; return (b("fee fie foe ") === "fee fie foe foo"); */}, res: { tr: true, babel: true, es6tr: true, jsx: true, typescript: true, ejs: true, closure: true, edge: true, firefox23: true, chrome38: flag, chrome40: false, chrome45: true, webkit: true, node: flag, }, }, 'multiple parameters': { exec: function(){/* var c = (v, w, x, y, z) => "" + v + w + x + y + z; return (c(6, 5, 4, 3, 2) === "65432"); */}, res: { tr: true, babel: true, es6tr: true, jsx: true, typescript: true, ejs: true, closure: true, edge: true, firefox23: true, chrome38: flag, chrome40: false, chrome45: true, webkit: true, node: flag, }, }, 'lexical "this" binding': { exec: function(){/* var d = { x : "bar", y : function() { return z => this.x + z; }}.y(); var e = { x : "baz", y : d }; return d("ley") === "barley" && e.y("ley") === "barley"; */}, res: { tr: true, babel: true, es6tr: true, jsx: true, typescript: true, ejs: true, closure: true, edge: true, firefox23: true, chrome45: true, }, }, '"this" unchanged by call or apply': { exec: function(){/* var d = { x : "foo", y : function() { return () => this.x; }}; var e = { x : "bar" }; return d.y().call(e) === "foo" && d.y().apply(e) === "foo"; */}, res: { tr: true, closure: true, babel: true, es6tr: true, jsx: true, typescript: true, ejs: true, edge: true, firefox23: true, chrome45: true, }, }, 'can\'t be bound, can be curried': { exec: function(){/* var d = { x : "bar", y : function() { return z => this.x + z; }}; var e = { x : "baz" }; return d.y().bind(e, "ley")() === "barley"; */}, res: { tr: true, babel: true, es6tr: true, jsx: true, typescript: true, ejs: true, closure: true, edge: true, firefox23: true, chrome45: true, }, }, 'lexical "arguments" binding': { exec: function(){/* var f = (function() { return z => arguments[0]; }(5)); return f(6) === 5; */}, res: { tr: true, babel: true, closure: true, edge: true, firefox23: true, firefox24: false, chrome45: true, }, }, 'no line break between params and <code>=></code>': { exec: function(){/* return (() => { try { Function("x\n => 2")(); } catch(e) { return true; } })(); */}, res: { babel: true, tr: true, typescript: true, edge: true, firefox39: true, webkit: true, chrome45: true, }, }, 'no "prototype" property': { exec: function(){/* var a = () => 5; return !a.hasOwnProperty("prototype"); */}, res: { ejs: true, edge: true, firefox23: true, chrome39: flag, chrome40: false, chrome45: true, }, }, 'lexical "super" binding': { exec: function(){/* class B { qux() { return "quux"; } } class C extends B { baz() { return x => super.qux(); } } var arrow = new C().baz(); return arrow() === "quux"; */}, res: { tr: true, babel: true, closure: true, es6tr: true, jsx: true, typescript: true, edge: flag, chrome45: strict, }, }, 'lexical "new.target" binding': { exec: function(){/* function C() { return x => new.target; } return new C()() === C && C()() === undefined; */}, res: { firefox41: true, chrome46: flag, }, }, }, }, { name: 'const', category: 'bindings', significance: 'medium', link: 'http://www.ecma-international.org/ecma-262/6.0/#sec-let-and-const-declarations', subtests: { 'basic support': { exec: function() {/* const foo = 123; return (foo === 123); */}, res: { tr: true, babel: true, typescript: true, es6tr: true, ejs: true, closure: true, ie11: true, firefox11: true, chrome: true, safari51: true, webkit: true, opera: true, konq49: true, node: true, iojs: true, } }, 'is block-scoped': { exec: function() {/* const bar = 123; { const bar = 456; } return bar === 123; */}, res: { babel: true, typescript: true, es6tr: true, tr: true, ejs: true, closure: true, ie11: true, firefox36: true, webkit: true, } }, 'redefining a const is an error': { exec: function() {/* const baz = 1; try { Function("const foo = 1; foo = 2;")(); } catch(e) { return true; } */}, res: { tr: true, babel: true, typescript: true, es6tr: true, ejs: true, closure: true, ie11: true, firefox36: true, webkit: true, } }, 'temporal dead zone': { exec: function(){/* var passed = (function(){ try { qux; } catch(e) { return true; }}()); function fn() { passed &= qux === 456; } const qux = 456; fn(); return passed; */}, res: { babel: flag, typescript: true, ie11: true, firefox36: true, webkit: true, }, }, 'basic support (strict mode)': { exec: function() {/* "use strict"; const foo = 123; return (foo === 123); */}, res: { tr: true, babel: true, typescript: true, es6tr: true, ejs: true, closure: true, ie11: true, firefox11: true, chrome: flag, chrome41: true, webkit: true, konq49: true, node: flag, iojs: true, } }, 'is block-scoped (strict mode)': { exec: function() {/* 'use strict'; const bar = 123; { const bar = 456; } return bar === 123; */}, res: { babel: true, typescript: true, es6tr: true, tr: true, ejs: true, closure: true, chrome19dev: flag, chrome41: true, ie11: true, firefox36: true, webkit: true, node: flag, iojs: true, } }, 'redefining a const (strict mode)': { exec: function() {/* 'use strict'; const baz = 1; try { Function("'use strict'; const foo = 1; foo = 2;")(); } catch(e) { return true; } */}, res: { tr: true, babel: true, typescript: true, es6tr: true, ejs: true, closure: true, ie11: true, firefox11: true, chrome21dev: flag, chrome41: true, webkit: true, node: flag, iojs: true, } }, 'temporal dead zone (strict mode)': { exec: function(){/* 'use strict'; var passed = (function(){ try { qux; } catch(e) { return true; }}()); function fn() { passed &= qux === 456; } const qux = 456; fn(); return passed; */}, res: { babel: flag, typescript: true, ie11: true, firefox36: true, chrome19dev: flag, chrome41: true, webkit: true, node: flag, iojs: true, }, }, } }, { name: 'let', category: 'bindings', significance: 'medium', link: 'http://www.ecma-international.org/ecma-262/6.0/#sec-let-and-const-declarations', subtests: { 'basic support': { exec: function(){/* let foo = 123; return (foo === 123); */}, res: { tr: true, babel: true, typescript: true, es6tr: true, ejs: true, closure: true, ie11: true, firefox11: { val: flag, note_id: 'fx-let', note_html: 'Available for code in a <code>&lt;script type="application/javascript;version=1.7"></code> (or <code>version=1.8</code>) tag.' }, webkit: true, }, }, 'is block-scoped': { exec: function(){/* let bar = 123; { let bar = 456; } return bar === 123; */}, res: { tr: true, babel: true, typescript: true, es6tr: true, ejs: true, closure: true, ie11: true, firefox11: { val: flag, note_id: 'fx-let', }, webkit: true, }, }, 'for-loop statement scope': { exec: function(){/* let baz = 1; for(let baz = 0; false; false) {} return baz === 1; */}, res: { tr: true, ejs: true, es6tr: true, babel: true, typescript: true, closure: true, ie11: true, firefox11: { val: flag, note_id: 'fx-let', }, webkit: true, }, }, 'temporal dead zone': { exec: function(){/* var passed = (function(){ try { qux; } catch(e) { return true; }}()); function fn() { passed &= qux === 456; } let qux = 456; fn(); return passed; */}, res: { babel: flag, typescript: true, ejs: true, ie11: true, firefox35: { val: flag, note_id: 'fx-let', }, webkit: true, }, }, 'for-loop iteration scope': { exec: function(){/* let scopes = []; for(let i = 0; i < 2; i++) { scopes.push(function(){ return i; }); } let passed = (scopes[0]() === 0 && scopes[1]() === 1); scopes = []; for(let i in { a:1, b:1 }) { scopes.push(function(){ return i; }); } passed &= (scopes[0]() === "a" && scopes[1]() === "b"); return passed; */}, res: { tr: true, babel: true, typescript: typescript.fallthrough, ejs: true, closure: true, firefox39: { val: flag, note_id: 'fx-let', }, webkit: true, }, }, 'basic support (strict mode)': { exec: function(){/* 'use strict'; let foo = 123; return (foo === 123); */}, res: { tr: true, babel: true, typescript: true, es6tr: true, ejs: true, closure: true, ie11: true, chrome19dev: flag, chrome41: true, node: flag, iojs: true, firefox11: { val: flag, note_id: 'fx-let' }, webkit: true, }, }, 'is block-scoped (strict mode)': { exec: function(){/* 'use strict'; let bar = 123; { let bar = 456; } return bar === 123; */}, res: { tr: true, babel: true, typescript: true, es6tr: true, ejs: true, closure: true, ie11: true, firefox11: { val: flag, note_id: 'fx-let', }, chrome19dev: flag, chrome41: true, webkit: true, node: flag, iojs: true, }, }, 'for-loop statement scope (strict mode)': { exec: function(){/* 'use strict'; let baz = 1; for(let baz = 0; false; false) {} return baz === 1; */}, res: { tr: true, babel: true, typescript: true, es6tr: true, ejs: true, closure: true, ie11: true, firefox11: { val: flag, note_id: 'fx-let', }, chrome19dev: flag, chrome41: true, webkit: true, node: flag, iojs: true, }, }, 'temporal dead zone (strict mode)': { exec: function(){/* 'use strict'; var passed = (function(){ try { qux; } catch(e) { return true; }}()); function fn() { passed &= qux === 456; } let qux = 456; fn(); return passed; */}, res: { babel: flag, typescript: true, ejs: true, ie11: true, firefox35: { val: flag, note_id: 'fx-let', }, chrome19dev: flag, chrome41: true, webkit: true, node: flag, iojs: true, }, }, 'for-loop iteration scope (strict mode)': { exec: function(){/* 'use strict'; let scopes = []; for(let i = 0; i < 2; i++) { scopes.push(function(){ return i; }); } let passed = (scopes[0]() === 0 && scopes[1]() === 1); scopes = []; for(let i in { a:1, b:1 }) { scopes.push(function(){ return i; }); } passed &= (scopes[0]() === "a" && scopes[1]() === "b"); return passed; */}, res: { tr: true, babel: true, typescript: typescript.fallthrough, ejs: true, closure: true, chrome37: flag, chrome41: true, webkit: true, node: flag, iojs: true, firefox39: { val: flag, note_id: 'fx-let', }, }, }, }, }, { name: 'default function parameters', category: 'syntax', significance: 'medium', link: 'http://www.ecma-international.org/ecma-262/6.0/#sec-functiondeclarationinstantiation', subtests: { 'basic functionality': { exec: function(){/* return (function (a = 1, b = 2) { return a === 3 && b === 2; }(3)); */}, res: { tr: true, babel: true, es6tr: true, ejs: true, closure: true, typescript: true, firefox16: true, edge: flag, }, }, 'explicit undefined defers to the default': { exec: function(){/* return (function (a = 1, b = 2) { return a === 1 && b === 3; }(undefined, 3)); */}, res: { tr: true, babel: true, es6tr: true, ejs: true, closure: true, typescript: true, firefox18: true, edge: flag, }, }, 'defaults can refer to previous params': { exec: function(){/* return (function (a, b = a) { return b === 5; }(5)); */}, res: { tr: true, babel: true, es6tr: true, ejs: true, closure: true, typescript: true, firefox16: true, edge: flag, }, }, 'temporal dead zone': { exec: function(){/* return (function(x = 1) { try { eval("(function(a=a){}())"); return false; } catch(e) {} try { eval("(function(a=b,b){}())"); return false; } catch(e) {} return true; }()); */}, res: { babel: true, typescript: true, edge: flag, }, }, 'separate scope': { exec: function(){/* return (function(a=function(){ return typeof b === 'undefined'; }){ var b = 1; return a(); }()); */}, res: { babel: true, closure: true, edge: flag, }, }, 'new Function() support': { exec: function() {/* return new Function("a = 1", "b = 2", "return a === 3 && b === 2;" )(3); */}, res: { typescript: typescript.fallthrough, edge: flag, }, }, } }, { name: 'rest parameters', category: 'syntax', significance: 'medium', link: 'http://www.ecma-international.org/ecma-262/6.0/#sec-function-definitions', subtests: { 'basic functionality': { exec: function() {/* return (function (foo, ...args) { return args instanceof Array && args + "" === "bar,baz"; }("foo", "bar", "baz")); */}, res: { tr: true, babel: true, es6tr: true, ejs: true, closure: true, jsx: true, typescript: true, edge: true, firefox16: true, chrome44: flag, }, }, 'function \'length\' property': { exec: function() {/* return function(a, ...b){}.length === 1 && function(...c){}.length === 0; */}, res: { tr: true, babel: true, es6tr: true, ejs: true, jsx: true, typescript: true, edge: true, firefox16: true, chrome44: flag, }, }, 'arguments object interaction': { exec: function() {/* return (function (foo, ...args) { foo = "qux"; // The arguments object is not mapped to the // parameters, even outside of strict mode. return arguments.length === 3 && arguments[0] === "foo" && arguments[1] === "bar" && arguments[2] === "baz"; }("foo", "bar", "baz")); */}, res: { babel: true, tr: true, chrome44: flag, edge: true, }, }, 'can\'t be used in setters': { exec: function() {/* return (function (...args) { try { eval("({set e(...args){}})"); } catch(e) { return true; } }()); */}, res: { babel: true, tr: true, closure: true, jsx: true, typescript: true, edge: true, firefox38: true, }, }, 'new Function() support': { exec: function() {/* return new Function("a", "...b", "return b instanceof Array && a+b === 'foobar,baz';" )('foo','bar','baz'); */}, res: { edge: true, firefox16: true, chrome44: flag, }, }, }, }, { name: 'spread (...) operator', category: 'syntax', significance: 'large', link: 'http://www.ecma-international.org/ecma-262/6.0/#sec-argument-lists-runtime-semantics-argumentlistevaluation', subtests: { 'with arrays, in function calls': { exec: function () {/* return Math.max(...[1, 2, 3]) === 3 */}, res: { tr: true, babel: true, typescript: true, es6tr: true, jsx: true, ejs: true, closure: true, edge: true, firefox27: true, safari71_8: true, webkit: true, chrome44: flag, chrome45: true, }, }, 'with arrays, in array literals': { exec: function() {/* return [...[1, 2, 3]][2] === 3; */}, res: { tr: true, babel: true, typescript: true, es6tr: true, ejs: true, closure: true, edge: true, firefox16: true, safari71_8: true, webkit: true, chrome45: true, }, }, 'with strings, in function calls': { exec: function() {/* return Math.max(..."1234") === 4; */}, res: { tr: true, babel: true, ejs: true, edge: true, firefox27: true, chrome44: flag, chrome45: true, }, }, 'with strings, in array literals': { exec: function() {/* return ["a", ..."bcd", "e"][3] === "d"; */}, res: { tr: true, babel: true, ejs: true, edge: true, firefox17: true, webkit: true, chrome45: true, }, }, 'with astral plane strings, in function calls': { exec: function() {/* return Array(..."𠮷𠮶")[0] === "𠮷"; */}, res: { tr: true, babel: true, ejs: true, firefox27: true, chrome44: flag, chrome45: true, edge: true, }, }, 'with astral plane strings, in array literals': { exec: function() {/* return [..."𠮷𠮶"][0] === "𠮷"; */}, res: { tr: true, babel: true, ejs: true, firefox27: true, webkit: true, edge: true, chrome45: true, }, }, 'with generator instances, in calls': { exec: function () {/* var iterable = (function*(){ yield 1; yield 2; yield 3; }()); return Math.max(...iterable) === 3; */}, res: { tr: true, babel: true, ejs: true, firefox27: true, chrome44: flag, chrome45: true, edge: flag, }, }, 'with generator instances, in arrays': { exec: function () {/* var iterable = (function*(){ yield "b"; yield "c"; yield "d"; }()); return ["a", ...iterable, "e"][3] === "d"; */}, res: { tr: true, babel: true, ejs: true, firefox27: true, chrome44: flag, chrome45: true, edge: flag, }, }, 'with generic iterables, in calls': { exec: function () {/* var iterable = global.__createIterableObject([1, 2, 3]); return Math.max(...iterable) === 3; */}, res: { tr: true, babel: true, es6tr: { val: true, note_id: 'compiler-iterable', note_html: 'This compiler requires generic iterables have either a <code>Symbol.iterator</code> or non-standard <code>"@@iterator"</code> method.' }, ejs: true, firefox36: true, chrome44: flag, chrome45: true, edge: true, }, }, 'with generic iterables, in arrays': { exec: function () {/* var iterable = global.__createIterableObject(["b", "c", "d"]); return ["a", ...iterable, "e"][3] === "d"; */}, res: { tr: true, babel: true, es6tr: { val: true, note_id: 'compiler-iterable' }, ejs: true, edge: true, firefox36: true, webkit: true, chrome45: true, }, }, 'with instances of iterables, in calls': { exec: function () {/* var iterable = global.__createIterableObject([1, 2, 3]); return Math.max(...Object.create(iterable)) === 3; */}, res: { tr: true, babel: true, es6tr: { val: true, note_id: 'compiler-iterable' }, firefox36: true, chrome44: flag, chrome45: true, edge: true }, }, 'with instances of iterables, in arrays': { exec: function () {/* var iterable = global.__createIterableObject(["b", "c", "d"]); return ["a", ...Object.create(iterable), "e"][3] === "d"; */}, res: { tr: true, babel: true, es6tr: { val: true, note_id: 'compiler-iterable' }, edge: true, firefox36: true, webkit: true, chrome45: true, }, }, } }, { name: 'class', category: 'functions', significance: 'large', link: 'http://www.ecma-international.org/ecma-262/6.0/#sec-class-definitions', subtests: { 'class statement': { exec: function () {/* class C {} return typeof C === "function"; */}, res: { tr: true, babel: true, es6tr: true, ejs: true, jsx: true, closure: true, edge: flag, webkit: true, iojs: strict, chrome41: strict, typescript: true, }, }, 'is block-scoped': { exec: function () {/* class C {} var c1 = C; { class C {} var c2 = C; } return C === c1; */}, res: { babel: true, jsx: true, edge: flag, chrome41: strict, iojs: strict, }, }, 'class expression': { exec: function () {/* return typeof class C {} === "function"; */}, res: { tr: true, babel: true, typescript: true, es6tr: true, jsx: true, ejs: true, edge: flag, webkit: true, chrome41: strict, iojs: strict, }, }, 'anonymous class': { exec: function () {/* return typeof class {} === "function"; */}, res: { tr: true, babel: true, typescript: true, es6tr: true, jsx: true, ejs: true, edge: flag, webkit: true, chrome41: strict, iojs: strict, }, }, 'constructor': { exec: function () {/* class C { constructor() { this.x = 1; } } return C.prototype.constructor === C && new C().x === 1; */}, res: { tr: true, babel: true, typescript: true, es6tr: true, jsx: true, ejs: true, closure: true, edge: flag, webkit: true, chrome41: strict, iojs: strict, }, }, 'prototype methods': { exec: function () {/* class C { method() { return 2; } } return typeof C.prototype.method === "function" && new C().method() === 2; */}, res: { tr: true, babel: true, typescript: true, es6tr: true, jsx: true, ejs: true, closure: true, edge: flag, webkit: true, chrome41: strict, iojs: strict, }, }, 'string-keyed methods': { exec: function () {/* class C { "foo bar"() { return 2; } } return typeof C.prototype["foo bar"] === "function" && new C()["foo bar"]() === 2; */}, res: { tr: true, babel: true, typescript: true, es6tr: true, jsx: true, ejs: true, edge: flag, webkit: true, chrome41: strict, iojs: strict, }, }, 'computed prototype methods': { exec: function () {/* var foo = "method"; class C { [foo]() { return 2; } } return typeof C.prototype.method === "function" && new C().method() === 2; */}, res: { tr: true, babel: true, typescript: true, es6tr: true, jsx: true, ejs: true, closure: true, edge: flag, chrome45: strict, }, }, 'static methods': { exec: function () {/* class C { static method() { return 3; } } return typeof C.method === "function" && C.method() === 3; */}, res: { tr: true, babel: true, typescript: true, es6tr: true, jsx: true, ejs: true, closure: true, edge: flag, webkit: true, chrome41: strict, iojs: strict, }, }, 'computed static methods': { exec: function () {/* var foo = "method"; class C { static [foo]() { return 3; } } return typeof C.method === "function" && C.method() === 3; */}, res: { tr: true, babel: true, typescript: true, es6tr: true, jsx: true, ejs: true, closure: true, edge: flag, chrome45: strict, }, }, 'accessor properties': { exec: function () {/* var baz = false; class C { get foo() { return "foo"; } set bar(x) { baz = x; } } new C().bar = true; return new C().foo === "foo" && baz; */}, res: { tr: true, babel: true, closure: true, typescript: true, jsx: true, es6tr: true, ejs: true, edge: flag, webkit: true, iojs: strict, chrome41: strict, }, }, 'computed accessor properties': { exec: function () {/* var garply = "foo", grault = "bar", baz = false; class C { get [garply]() { return "foo"; } set [grault](x) { baz = x; } } new C().bar = true; return new C().foo === "foo" && baz; */}, res: { tr: true, babel: true, typescript: true, es6tr: true, ejs: true, edge: flag, chrome45: strict, }, }, 'static accessor properties': { exec: function () {/* var baz = false; class C { static get foo() { return "foo"; } static set bar(x) { baz = x; } } C.bar = true; return C.foo === "foo" && baz; */}, res: { tr: true, babel: true, typescript: true, jsx: true, es6tr: true, ejs: true, edge: flag, iojs: strict, chrome41: strict, webkit: true, }, }, 'computed static accessor properties': { exec: function () {/* var garply = "foo", grault = "bar", baz = false; class C { static get [garply]() { return "foo"; } static set [grault](x) { baz = x; } } C.bar = true; return C.foo === "foo" && baz; */}, res: { tr: true, babel: true, typescript: true, es6tr: true, ejs: true, edge: flag, chrome45: strict, }, }, 'class name is lexically scoped': { exec: function () {/* class C { method() { return typeof C === "function"; } } var M = C.prototype.method; C = undefined; return C === undefined && M(); */}, res: { tr: true, babel: true, typescript: true, es6tr: true, edge: flag, chrome41: strict, iojs: strict, }, }, 'computed names, temporal dead zone': { exec: function () {/* try { var B = class C { [C](){} } } catch(e) { return true; } */}, res: { edge: flag, chrome45: strict, }, }, 'methods aren\'t enumerable': { exec: function () {/* class C { foo() {} static bar() {} } return !C.prototype.propertyIsEnumerable("foo") && !C.propertyIsEnumerable("bar"); */}, res: { babel: true, jsx: true, chrome42: strict, webkit: true, }, }, 'implicit strict mode': { exec: function () {/* class C { static method() { return this === undefined; } } return (0,C.method)(); */}, res: { tr: true, babel: true, es6tr: true, jsx: true, edge: flag, webkit: true, chrome41: strict, iojs: strict, }, }, 'constructor requires new': { exec: function () {/* class C {} try { C(); } catch(e) { return true; } */}, res: { babel: true, typescript: true, webkit: true, chrome43: strict, }, }, 'extends': { exec: function () {/* class B {} class C extends B {} return new C() instanceof B && B.isPrototypeOf(C); */}, res: (temp.extendsRes = { es6tr: { val: false, note_id: 'compiler-proto', note_html: 'Requires native support for <code>Object.prototype.__proto__</code>', }, babel: { val: false, note_id: 'compiler-proto' }, tr: { val: false, note_id: 'compiler-proto' }, typescript: { val: false, note_id: 'typescript-extends', note_html: 'TypeScript transforms <code>extends</code> into code that copies static properties from the superclass (but uses the prototype chain for instance properties).'}, ejs: true, closure: { val: false, note_id: 'compiled-extends', note_html: 'This compiler transforms <code>extends</code> into code that copies properties from the superclass, instead of using the prototype chain.' }, jsx: { val: false, note_id: 'compiled-extends' }, edge: flag, webkit: true, iojs: strict, chrome41: strict, }), }, 'extends expressions': { exec: function () {/* var B; class C extends (B = class {}) {} return new C() instanceof B && B.isPrototypeOf(C); */}, res: { es6tr: { val: false, note_id: 'compiler-proto' }, babel: { val: false, note_id: 'compiler-proto' }, tr: { val: false, note_id: 'compiler-proto' }, typescript: { val: false, note_id: 'typescript-extends', }, ejs: true, jsx: { val: false, note_id: 'compiled-extends' }, edge: flag, webkit: true, iojs: strict, chrome41: strict, }, }, 'extends null': { exec: function () {/* class C extends null { constructor() { return Object.create(null); } } return Function.prototype.isPrototypeOf(C) && Object.getPrototypeOf(C.prototype) === null; */}, res: { babel: true, tr: true, ejs: true, es6tr: true, jsx: true, edge: flag, iojs: strict, chrome41: strict, webkit: true, }, }, 'new.target': { exec: function () {/* var passed = false; new function f() { passed = new.target === f; }(); class A { constructor() { passed &= new.target === B; } } class B extends A {} new B(); return passed; */}, res: { webkit: true, chrome46: flag, }, }, }, }, { name: 'super', category: 'functions', significance: 'medium', link: 'http://www.ecma-international.org/ecma-262/6.0/#sec-super-keyword', subtests: { 'statement in constructors': { exec: function() {/* var passed = false; class B { constructor(a) { passed = (a === "barbaz"); } } class C extends B { constructor(a) { super("bar" + a); } } new C("baz"); return passed; */}, res: { tr: true, babel: true, jsx: true, typescript: true, closure: true, es6tr: true, ejs: true, edge: flag, webkit: true, iojs: strict, chrome41: strict, }, }, 'expression in constructors': { exec: function() {/* class B { constructor(a) { return ["foo" + a]; } } class C extends B { constructor(a) { return super("bar" + a); } } return new C("baz")[0] === "foobarbaz"; */}, res: { tr: true, babel: true, jsx: true, typescript: true, closure: true, es6tr: true, ejs: true, edge: flag, webkit: true, chrome43: strict, }, }, 'in methods, property access': { exec: function() {/* class B {} B.prototype.qux = "foo"; B.prototype.corge = "baz"; class C extends B { quux(a) { return super.qux + a + super["corge"]; } } C.prototype.qux = "garply"; return new C().quux("bar") === "foobarbaz"; */},