caniuse-es-db
Version:
ECMAScript compatibility database based on kangax/compat-table
2,003 lines (1,993 loc) • 284 kB
JavaScript
// 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 <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 30,<br>OP 17',
obsolete: true,
note_id: 'experimental-flag',
},
chrome31: {
full: 'Chrome, Opera',
short: 'CH 31,<br>OP 18',
obsolete: true,
note_id: 'experimental-flag',
},
chrome33: {
full: 'Chrome, Opera',
short: 'CH 32-33,<br>OP 19-20',
obsolete: true,
note_id: 'experimental-flag',
},
chrome34: {
full: 'Chrome, Opera',
short: 'CH 34,<br>OP 21',
obsolete: true,
note_id: 'experimental-flag',
},
chrome35: {
full: 'Chrome, Opera',
short: 'CH 35,<br>OP 22',
obsolete: true,
note_id: 'experimental-flag',
},
chrome36: {
full: 'Chrome, Opera',
short: 'CH 36,<br>OP 23',
obsolete: true,
note_id: 'experimental-flag',
},
chrome37: {
full: 'Chrome, Opera',
short: 'CH 37,<br>OP 24',
obsolete: true,
note_id: 'experimental-flag',
},
chrome38: {
full: 'Chrome, Opera',
short: 'CH 38,<br>OP 25',
obsolete: true,
note_id: 'experimental-flag',
},
chrome39: {
full: 'Chrome, Opera',
short: 'CH 39,<br>OP 26',
obsolete: true,
note_id: 'experimental-flag',
},
chrome40: {
full: 'Chrome, Opera',
short: 'CH 40,<br>OP 27',
obsolete: true,
note_id: 'experimental-flag',
},
chrome41: {
full: 'Chrome, Opera',
short: 'CH 41,<br>OP 28',
obsolete: true,
note_id: 'experimental-flag',
},
chrome42: {
full: 'Chrome, Opera',
short: 'CH 42,<br>OP 29',
obsolete: true,
note_id: 'experimental-flag',
},
chrome43: {
full: 'Chrome, Opera',
short: 'CH 43,<br>OP 30',
obsolete: true,
note_id: 'experimental-flag',
},
chrome44: {
full: 'Chrome, Opera',
short: 'CH 44,<br>OP 31',
note_id: 'experimental-flag',
},
chrome45: {
full: 'Chrome, Opera',
short: 'CH 45,<br>OP 32',
unstable: true,
note_id: 'experimental-flag',
},
chrome46: {
full: 'Chrome, Opera',
short: 'CH 46,<br>OP 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><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";
*/},