Rhino ES2015 Support
1.7R4
(these versions have identical results)
7% complete7% complete
|
1.7R5
(these versions have identical results)
7% complete7% complete
|
1.7.7.2
(these versions have identical results)
22% complete18% complete
|
1.7.10
(these versions have identical results)
22% complete18% complete
|
1.7.11
(these versions have identical results)
34% complete20% complete
|
1.7.12
(these versions have identical results)
35% complete20% complete
|
1.7.13
(these versions have identical results)
38% complete20% complete
|
1.7.14
(these versions have identical results)
42% complete22% complete
|
1.7.15
(these versions have identical results)
46% complete24% complete
|
1.8.0
(these versions have identical results)
62% complete62% complete
|
---|
proper tail calls (tail call optimisation) |
||||||||||
direct recursion
?
function(){
"use strict";
return (function f(n){
if (n <= 0) {
return "foo";
}
return f(n - 1);
}(1e6)) === "foo"; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
mutual recursion
?
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"; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
default function parameters |
||||||||||
basic functionality
?
function(){
return (function (a = 1, b = 2) { return a === 3 && b === 2; }(3)); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
explicit undefined defers to the default
?
function(){
return (function (a = 1, b = 2) { return a === 1 && b === 3; }(undefined, 3)); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
defaults can refer to previous params
?
function(){
return (function (a, b = a) { return b === 5; }(5)); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
arguments object interaction
?
function(){
return (function (a = "baz", b = "qux", c = "quux") {
a = "corge";
// The arguments object is not mapped to the
// parameters, even outside of strict mode.
return arguments.length === 2
&& arguments[0] === "foo"
&& arguments[1] === "bar";
}("foo", "bar")); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
temporal dead zone
?
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;
}()); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
separate scope
?
function(){
return (function(a=function(){
return typeof b === 'undefined';
}){
var b = 1;
return a();
}()); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
new Function() support
?
function(){
return new Function("a = 1", "b = 2",
"return a === 3 && b === 2;"
)(3); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
rest parameters |
||||||||||
basic functionality
?
function(){
return (function (foo, ...args) {
return args instanceof Array && args + "" === "bar,baz";
}("foo", "bar", "baz")); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Yes Yes |
function 'length' property
?
function(){
return function(a, ...b){}.length === 1 && function(...c){}.length === 0; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Yes Yes |
arguments object interaction
?
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")); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
No No |
can't be used in setters
?
function(){
return (function (...args) {
try {
eval("({set e(...args){}})");
} catch(e) {
return true;
}
}()); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
No No |
new Function() support
?
function(){
return new Function("a", "...b",
"return b instanceof Array && a+b === 'foobar,baz';"
)('foo','bar','baz'); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Yes Yes |
spread syntax for iterable objects |
||||||||||
with arrays, in function calls
?
function(){
return Math.max(...[1, 2, 3]) === 3 }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
with arrays, in array literals
?
function(){
return [...[1, 2, 3]][2] === 3; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
with sparse arrays, in function calls
?
function(){
var a = Array(...[,,]);
return "0" in a && "1" in a && '' + a[0] + a[1] === "undefinedundefined"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
with sparse arrays, in array literals
?
function(){
var a = [...[,,]];
return "0" in a && "1" in a && '' + a[0] + a[1] === "undefinedundefined"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
with strings, in function calls
?
function(){
return Math.max(..."1234") === 4; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
with strings, in array literals
?
function(){
return ["a", ..."bcd", "e"][3] === "d"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
with astral plane strings, in function calls
?
function(){
return Array(..."𠮷𠮶")[0] === "𠮷"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
with astral plane strings, in array literals
?
function(){
return [..."𠮷𠮶"][0] === "𠮷"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
with generator instances, in calls
?
function(){
var iterable = (function*(){ yield 1; yield 2; yield 3; }());
return Math.max(...iterable) === 3; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
with generator instances, in arrays
?
function(){
var iterable = (function*(){ yield "b"; yield "c"; yield "d"; }());
return ["a", ...iterable, "e"][3] === "d"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
with generic iterables, in calls
?
function(){
var iterable = global.__createIterableObject([1, 2, 3]);
return Math.max(...iterable) === 3; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
with generic iterables, in arrays
?
function(){
var iterable = global.__createIterableObject(["b", "c", "d"]);
return ["a", ...iterable, "e"][3] === "d"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
with instances of iterables, in calls
?
function(){
var iterable = global.__createIterableObject([1, 2, 3]);
return Math.max(...Object.create(iterable)) === 3; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
with instances of iterables, in arrays
?
function(){
var iterable = global.__createIterableObject(["b", "c", "d"]);
return ["a", ...Object.create(iterable), "e"][3] === "d"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
spreading non-iterables is a runtime error
?
function(){
try {
Math.max(...2);
} catch(e) {
return Math.max(...[1, 2, 3]) === 3;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
object literal extensions |
||||||||||
computed properties
?
function(){
var x = 'y';
return ({ [x]: 1 }).y === 1; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
shorthand properties
?
function(){
var a = 7, b = 8, c = {a,b};
return c.a === 7 && c.b === 8; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Yes Yes |
shorthand methods
?
function(){
return ({ y() { return 2; } }).y() === 2; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
string-keyed shorthand methods
?
function(){
return ({ "foo bar"() { return 4; } })["foo bar"]() === 4; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
computed shorthand methods
?
function(){
var x = 'y';
return ({ [x](){ return 1 } }).y() === 1; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
computed accessors
?
function(){
var x = 'y',
valueSet,
obj = {
get [x] () { return 1 },
set [x] (value) { valueSet = value }
};
obj.y = 'foo';
return obj.y === 1 && valueSet === 'foo'; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
for..of loops |
||||||||||
with arrays
?
function(){
var arr = [5];
for (var item of arr)
return item === 5; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
with sparse arrays
?
function(){
var arr = [,,];
var count = 0;
for (var item of arr)
count += (item === void undefined);
return count === 2; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
with strings
?
function(){
var str = "";
for (var item of "foo")
str += item;
return str === "foo"; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
with astral plane strings
?
function(){
var str = "";
for (var item of "𠮷𠮶")
str += item + " ";
return str === "𠮷 𠮶 "; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
with generator instances
?
function(){
var result = "";
var iterable = (function*(){ yield 1; yield 2; yield 3; }());
for (var item of iterable) {
result += item;
}
return result === "123"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
with generic iterables
?
function(){
var result = "";
var iterable = global.__createIterableObject([1, 2, 3]);
for (var item of iterable) {
result += item;
}
return result === "123"; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
with instances of generic iterables
?
function(){
var result = "";
var iterable = global.__createIterableObject([1, 2, 3]);
for (var item of Object.create(iterable)) {
result += item;
}
return result === "123"; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
iterator closing, break
?
function(){
var closed = false;
var iter = __createIterableObject([1, 2, 3], {
'return': function(){ closed = true; return {}; }
});
for (var it of iter) break;
return closed; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
iterator closing, throw
?
function(){
var closed = false;
var iter = __createIterableObject([1, 2, 3], {
'return': function(){ closed = true; return {}; }
});
try {
for (var it of iter) throw 0;
} catch(e){}
return closed; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
octal and binary literals |
||||||||||
octal literals
?
function(){
return 0o10 === 8 && 0O10 === 8; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
binary literals
?
function(){
return 0b10 === 2 && 0B10 === 2; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
octal supported by Number()
?
function(){
return Number('0o1') === 1; }
|
No No |
No No |
No No |
No Flag |
No Flag |
No Flag |
No Flag |
No Flag |
No Flag |
Yes Yes |
binary supported by Number()
?
function(){
return Number('0b1') === 1; }
|
No No |
No No |
No No |
No Flag |
No Flag |
No Flag |
No Flag |
No Flag |
No Flag |
Yes Yes |
template literals |
||||||||||
basic functionality
?
function(){
var a = "ba", b = "QUX";
return `foo bar
${a + "z"} ${b.toLowerCase()}` === "foo bar\nbaz qux"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
toString conversion
?
function(){
var a = {
toString: function() { return "foo"; },
valueOf: function() { return "bar"; }
};
return `${a}` === "foo"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
tagged template literals
?
function(){
var called = false;
function fn(parts, a, b) {
called = true;
return parts instanceof Array &&
parts[0] === "foo" &&
parts[1] === "bar\n" &&
parts.raw[0] === "foo" &&
parts.raw[1] === "bar\\n" &&
a === 123 &&
b === 456;
}
return fn `foo${123}bar\n${456}` && called; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
passed array is frozen
?
function(){
return (function(parts) {
return Object.isFrozen(parts) && Object.isFrozen(parts.raw);
}) `foo${0}bar${0}baz`; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
line break normalisation
?
function(){
var cr = eval("`x" + String.fromCharCode(13) + "y`");
var lf = eval("`x" + String.fromCharCode(10) + "y`");
var crlf = eval("`x" + String.fromCharCode(13,10) + "y`");
return cr.length === 3 && lf.length === 3 && crlf.length === 3
&& cr[1] === lf[1] && lf[1] === crlf[1] && crlf[1] === '\n'; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
TemplateStrings call site caching
?
function(){
// TemplateStrings caching was changed from per-contents to
// per-call-site.
// https://github.com/tc39/ecma262/pull/890
function strings(array) {
return array;
}
function getStrings() {
return strings`foo`;
}
var original = getStrings();
var other = strings`foo`;
return original === getStrings() && original !== other; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
TemplateStrings permanent caching
?
function(){
function strings(array) {
return array;
}
function getStrings() {
return strings`foo`;
}
var original = getStrings();
var newed = new getStrings();
return original === getStrings() && original === newed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
RegExp "y" and "u" flags |
||||||||||
"y" flag
?
function(){
var re = new RegExp('\\w', 'y');
re.exec('xy');
return (re.exec('xy')[0] === 'y'); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Yes Yes |
"y" flag, lastIndex
?
function(){
var re = new RegExp('yy', 'y');
re.lastIndex = 3;
var result = re.exec('xxxyyxx')[0];
return result === 'yy' && re.lastIndex === 5; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Yes Yes |
"u" flag
?
function(){
return "𠮷".match(/^.$/u)[0].length === 2; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
"u" flag, non-BMP Unicode characters
?
function(){
return "𠮷x".match(/^.x$/u)[0].length === 3; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
"u" flag, Unicode code point escapes
?
function(){
return "𝌆".match(/\u{1d306}/u)[0].length === 2; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
"u" flag, case folding
?
function(){
return "ſ".match(/S/iu) && "S".match(/ſ/iu); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
destructuring, declarations |
||||||||||
with arrays
?
function(){
var [a, , [b], c] = [5, null, [6]];
return a === 5 && b === 6 && c === void undefined; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
with sparse arrays
?
function(){
var [a, , b] = [,,,];
return a === void undefined && b === void undefined; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
with strings
?
function(){
var [a, b, c] = "ab";
return a === "a" && b === "b" && c === void undefined; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
with astral plane strings
?
function(){
var [c] = "𠮷𠮶";
return c === "𠮷"; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
with generator instances
?
function(){
var [a, b, c] = (function*(){ yield 1; yield 2; }());
return a === 1 && b === 2 && c === void undefined; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
No No |
No No |
No No |
with generic iterables
?
function(){
var [a, b, c] = global.__createIterableObject([1, 2]);
return a === 1 && b === 2 && c === void undefined; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
with instances of generic iterables
?
function(){
var [a, b, c] = Object.create(global.__createIterableObject([1, 2]));
return a === 1 && b === 2 && c === void undefined; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
iterator closing
?
function(){
var closed = false;
var iter = global.__createIterableObject([1, 2, 3], {
'return': function(){ closed = true; return {}; }
});
var [a, b] = iter;
return closed; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
trailing commas in iterable patterns
?
function(){
var [a,] = [1];
return a === 1; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
with objects
?
function(){
var {c, x:d, e} = {c:7, x:8};
return c === 7 && d === 8 && e === void undefined; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
object destructuring with primitives
?
function(){
var {toFixed} = 2;
var {slice} = '';
return toFixed === Number.prototype.toFixed
&& slice === String.prototype.slice; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
trailing commas in object patterns
?
function(){
var {a,} = {a:1};
return a === 1; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
throws on null and undefined
?
function(){
try {
var {a} = null;
return false;
} catch(e) {
if (!(e instanceof TypeError))
return false;
}
try {
var {b} = void undefined;
return false;
} catch(e) {
if (!(e instanceof TypeError))
return false;
}
return true; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
computed properties
?
function(){
var qux = "corge";
var { [qux]: grault } = { corge: "garply" };
return grault === "garply"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
multiples in a single var statement
?
function(){
var [a,b] = [5,6], {c,d} = {c:7,d:8};
return a === 5 && b === 6 && c === 7 && d === 8; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
nested
?
function(){
var [e, {x:f, g}] = [9, {x:10}];
var {h, x:[i]} = {h:11, x:[12]};
return e === 9 && f === 10 && g === void undefined
&& h === 11 && i === 12; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
in for-in loop heads
?
function(){
for(var [i, j, k] in { qux: 1 }) {
return i === "q" && j === "u" && k === "x";
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
in for-of loop heads
?
function(){
for(var [i, j, k] of [[1,2,3]]) {
return i === 1 && j === 2 && k === 3;
} }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
in catch heads
?
function(){
try {
throw [1,2];
} catch([i,j]) {
try {
throw { k: 3, l: 4 };
} catch({k, l}) {
return i === 1 && j === 2 && k === 3 && l === 4;
}
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
rest
?
function(){
var [a, ...b] = [3, 4, 5];
var [c, ...d] = [6];
return a === 3 && b instanceof Array && (b + "") === "4,5" &&
c === 6 && d instanceof Array && d.length === 0; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
defaults
?
function(){
var {a = 1, b = 0, z:c = 3} = {b:2, z:undefined};
var [d = 0, e = 5, f = 6] = [4,,undefined];
return a === 1 && b === 2 && c === 3
&& d === 4 && e === 5 && f === 6; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
defaults, let temporal dead zone
?
function(){
var {a, b = 2} = {a:1};
try {
eval("let {c = c} = {};");
return false;
} catch(e){}
try {
eval("let {c = d, d} = {d:1};");
return false;
} catch(e){}
return a === 1 && b === 2; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
destructuring, assignment |
||||||||||
with arrays
?
function(){
var a,b,c;
[a, , [b], c] = [5, null, [6]];
return a === 5 && b === 6 && c === void undefined; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
with sparse arrays
?
function(){
var a, b;
[a, , b] = [,,,];
return a === void undefined && b === void undefined; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
with strings
?
function(){
var a,b,c;
[a, b, c] = "ab";
return a === "a" && b === "b" && c === void undefined; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
with astral plane strings
?
function(){
var c;
[c] = "𠮷𠮶";
return c === "𠮷"; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
with generator instances
?
function(){
var a,b,c;
[a, b, c] = (function*(){ yield 1; yield 2; }());
return a === 1 && b === 2 && c === void undefined; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
No No |
No No |
No No |
with generic iterables
?
function(){
var a,b,c;
[a, b, c] = global.__createIterableObject([1, 2]);
return a === 1 && b === 2 && c === void undefined; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
with instances of generic iterables
?
function(){
var a,b,c;
[a, b, c] = Object.create(global.__createIterableObject([1, 2]));
return a === 1 && b === 2 && c === void undefined; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
iterator closing
?
function(){
var closed = false;
var iter = global.__createIterableObject([1, 2, 3], {
'return': function(){ closed = true; return {}; }
});
var a,b;
[a, b] = iter;
return closed; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
iterable destructuring expression
?
function(){
var a, b, iterable = [1,2];
return ([a, b] = iterable) === iterable; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
chained iterable destructuring
?
function(){
var a,b,c,d;
[a,b] = [c,d] = [1,2];
return a === 1 && b === 2 && c === 1 && d === 2; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
trailing commas in iterable patterns
?
function(){
var a;
[a,] = [1];
return a === 1; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
with objects
?
function(){
var c,d,e;
({c, x:d, e} = {c:7, x:8});
return c === 7 && d === 8 && e === void undefined; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Yes Yes |
object destructuring with primitives
?
function(){
var toFixed, slice;
({toFixed} = 2);
({slice} = '');
return toFixed === Number.prototype.toFixed
&& slice === String.prototype.slice; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Yes Yes |
trailing commas in object patterns
?
function(){
var a;
({a,} = {a:1});
return a === 1; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Yes Yes |
object destructuring expression
?
function(){
var a, b, obj = { a:1, b:2 };
return ({a,b} = obj) === obj; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Yes Yes |
parenthesised left-hand-side is a syntax error
?
function(){
var a, b;
({a,b} = {a:1,b:2});
try {
eval("({a,b}) = {a:3,b:4};");
}
catch(e) {
return a === 1 && b === 2;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error No |
Error No |
No No |
chained object destructuring
?
function(){
var a,b,c,d;
({a,b} = {c,d} = {a:1,b:2,c:3,d:4});
return a === 1 && b === 2 && c === 3 && d === 4; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Yes Yes |
throws on null and undefined
?
function(){
var a,b;
try {
({a} = null);
return false;
} catch(e) {
if (!(e instanceof TypeError))
return false;
}
try {
({b} = void undefined);
return false;
} catch(e) {
if (!(e instanceof TypeError))
return false;
}
return true; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Yes Yes |
computed properties
?
function(){
var grault, qux = "corge";
({ [qux]: grault } = { corge: "garply" });
return grault === "garply"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
nested
?
function(){
var e,f,g,h,i;
[e, {x:f, g}] = [9, {x:10}];
({h, x:[i]} = {h:11, x:[12]});
return e === 9 && f === 10 && g === void undefined
&& h === 11 && i === 12; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Yes Yes |
rest
?
function(){
var a,b,c,d;
[a, ...b] = [3, 4, 5];
[c, ...d] = [6];
return a === 3 && b instanceof Array && (b + "") === "4,5" &&
c === 6 && d instanceof Array && d.length === 0; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
nested rest
?
function(){
var a = [1, 2, 3], first, last;
[first, ...[a[2], last]] = a;
return first === 1 && last === 3 && (a + "") === "1,2,2"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
empty patterns
?
function(){
[] = [1,2];
({} = {a:1,b:2});
return true; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
defaults
?
function(){
var a,b,c,d,e,f;
({a = 1, b = 0, z:c = 3} = {b:2, z:undefined});
[d = 0, e = 5, f = 6] = [4,,undefined];
return a === 1 && b === 2 && c === 3
&& d === 4 && e === 5 && f === 6; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
destructuring, parameters |
||||||||||
with arrays
?
function(){
return function([a, , [b], c]) {
return a === 5 && b === 6 && c === void undefined;
}([5, null, [6]]); }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
with sparse arrays
?
function(){
return function([a, , b]) {
return a === void undefined && b === void undefined;
}([,,,]); }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
with strings
?
function(){
return function([a, b, c]) {
return a === "a" && b === "b" && c === void undefined;
}("ab"); }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
with astral plane strings
?
function(){
return function([c]) {
return c === "𠮷";
}("𠮷𠮶"); }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
with generator instances
?
function(){
return function([a, b, c]) {
return a === 1 && b === 2 && c === void undefined;
}(function*(){ yield 1; yield 2; }()); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
No No |
No No |
No No |
with generic iterables
?
function(){
return function([a, b, c]) {
return a === 1 && b === 2 && c === void undefined;
}(global.__createIterableObject([1, 2])); }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
with instances of generic iterables
?
function(){
return function([a, b, c]) {
return a === 1 && b === 2 && c === void undefined;
}(Object.create(global.__createIterableObject([1, 2]))); }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
iterator closing
?
function(){
var closed = false;
var iter = global.__createIterableObject([1, 2, 3], {
'return': function(){ closed = true; return {}; }
});
(function([a,b]) {}(iter));
return closed; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
trailing commas in iterable patterns
?
function(){
return function([a,]) {
return a === 1;
}([1]); }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
with objects
?
function(){
return function({c, x:d, e}) {
return c === 7 && d === 8 && e === void undefined;
}({c:7, x:8}); }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
object destructuring with primitives
?
function(){
return function({toFixed}, {slice}) {
return toFixed === Number.prototype.toFixed
&& slice === String.prototype.slice;
}(2,''); }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
trailing commas in object patterns
?
function(){
return function({a,}) {
return a === 1;
}({a:1}); }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
throws on null and undefined
?
function(){
try {
(function({a}){}(null));
return false;
} catch(e) {}
try {
(function({b}){}(undefined));
return false;
} catch(e) {}
return true; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
computed properties
?
function(){
var qux = "corge";
return function({ [qux]: grault }) {
return grault === "garply";
}({ corge: "garply" }); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
nested
?
function(){
return function([e, {x:f, g}], {h, x:[i]}) {
return e === 9 && f === 10 && g === void undefined
&& h === 11 && i === 12;
}([9, {x:10}],{h:11, x:[12]}); }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
'arguments' interaction
?
function(){
return (function({a, x:b, y:e}, [c, d]) {
return arguments[0].a === 1 && arguments[0].x === 2
&& !("y" in arguments[0]) && arguments[1] + '' === "3,4";
}({a:1, x:2}, [3, 4])); }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
new Function() support
?
function(){
return new Function("{a, x:b, y:e}","[c, d]",
"return a === 1 && b === 2 && c === 3 && "
+ "d === 4 && e === void undefined;"
)({a:1, x:2}, [3, 4]); }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
in parameters, function 'length' property
?
function(){
return function({a, b}, [c, d]){}.length === 2; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
rest
?
function(){
return function([a, ...b], [c, ...d]) {
return a === 3 && b instanceof Array && (b + "") === "4,5" &&
c === 6 && d instanceof Array && d.length === 0;
}([3, 4, 5], [6]); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
empty patterns
?
function(){
return function ([],{}){
return arguments[0] + '' === "3,4" && arguments[1].x === "foo";
}([3,4],{x:"foo"}); }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
defaults
?
function(){
return (function({a = 1, b = 0, c = 3, x:d = 0, y:e = 5},
[f = 6, g = 0, h = 8]) {
return a === 1 && b === 2 && c === 3 && d === 4 &&
e === 5 && f === 6 && g === 7 && h === 8;
}({b:2, c:undefined, x:4},[, 7, undefined])); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
defaults, separate scope
?
function(){
return (function({a=function(){
return typeof b === 'undefined';
}}){
var b = 1;
return a();
}({})); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
defaults, new Function() support
?
function(){
return new Function("{a = 1, b = 0, c = 3, x:d = 0, y:e = 5}",
"return a === 1 && b === 2 && c === 3 && d === 4 && e === 5;"
)({b:2, c:undefined, x:4}); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
aliased defaults, arrow function
?
function(){
return ((a, {b: x = 0, c: y = 3}) => {
return a === 1 && x === 2 && y === 3;
})(1, {b: 2}); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
shorthand defaults, arrow function
?
function(){
return ((a, {b = 0, c = 3}) => {
return a === 1 && b === 2 && c === 3;
})(1, {b: 2}); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
duplicate identifier
?
function(){
try {
eval('var d = function d([d]) { return d };');
if (d([true]) !== true) return false;
} catch (e) {
return !(e instanceof SyntaxError);
}
try {
eval('var f = function f([id, id]) { return id }');
return false;
} catch (e) {
return e instanceof SyntaxError;
} }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Unicode code point escapes |
||||||||||
in strings
?
function(){
return '\u{1d306}' === '\ud834\udf06'; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
in identifiers
?
function(){
var \u{102C0} = 2;
return \u{102C0} === 2; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Yes Yes |
in property key definitions
?
function(){
var o = { \u{102C0} : 2 };
return o['\ud800\udec0'] === 2; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Yes Yes |
in property key accesses
?
function(){
var o = { '\ud800\udec0' : 2 };
return o.\u{102C0} === 2; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Yes Yes |
new.target |
||||||||||
in constructors
?
function(){
var passed = false;
new function f() {
passed = (new.target === f);
}();
(function() {
passed &= (new.target === void undefined);
}());
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
assignment is an early error
?
function(){
var passed = false;
new function f() {
passed = (new.target === f);
}();
try {
Function("new.target = function(){};");
} catch(e) {
return passed;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
const |
||||||||||
basic support
?
function(){
const foo = 123;
return (foo === 123); }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
is block-scoped
?
function(){
const bar = 123;
{ const bar = 456; }
return bar === 123; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
scope shadow resolution
?
function(){
try {
{ const bar = 456; }
const bar = 123;
return bar === 123;
} catch(e) {
return false;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
cannot be in statements
?
function(){
const bar = 1;
try {
Function("if(true) const baz = 1;")();
} catch(e) {
return true;
} }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
redefining a const is an error
?
function(){
const baz = 1;
try {
Function("const foo = 1; foo = 2;")();
} catch(e) {
return true;
} }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
for loop statement scope
?
function(){
const baz = 1;
for(const baz = 0; false;) {}
return baz === 1; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
for-in loop iteration scope
?
function(){
var scopes = [];
for(const i in { a:1, b:1 }) {
scopes.push(function(){ return i; });
}
return (scopes[0]() === "a" && scopes[1]() === "b"); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
for-of loop iteration scope
?
function(){
var scopes = [];
for(const i of ['a','b']) {
scopes.push(function(){ return i; });
}
return (scopes[0]() === "a" && scopes[1]() === "b"); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
temporal dead zone
?
function(){
var passed = (function(){ try { qux; } catch(e) { return true; }}());
function fn() { passed &= qux === 456; }
const qux = 456;
fn();
return passed; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
basic support (strict mode)
?
function(){
"use strict";
const foo = 123;
return (foo === 123); }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
is block-scoped (strict mode)
?
function(){
'use strict';
const bar = 123;
{ const bar = 456; }
return bar === 123; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
scope shadow resolution (strict mode)
?
function(){
'use strict';
try {
{ const bar = 456; }
const bar = 123;
return bar === 123;
} catch(e) {
return false;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
cannot be in statements (strict mode)
?
function(){
'use strict';
const bar = 1;
try {
Function("'use strict'; if(true) const baz = 1;")();
} catch(e) {
return true;
} }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
redefining a const (strict mode)
?
function(){
'use strict';
const baz = 1;
try {
Function("'use strict'; const foo = 1; foo = 2;")();
} catch(e) {
return true;
} }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
for loop statement scope (strict mode)
?
function(){
'use strict';
const baz = 1;
for(const baz = 0; false;) {}
return baz === 1; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
for-in loop iteration scope (strict mode)
?
function(){
'use strict';
var scopes = [];
for(const i in { a:1, b:1 }) {
scopes.push(function(){ return i; });
}
return (scopes[0]() === "a" && scopes[1]() === "b"); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
for-of loop iteration scope (strict mode)
?
function(){
'use strict';
var scopes = [];
for(const i of ['a','b']) {
scopes.push(function(){ return i; });
}
return (scopes[0]() === "a" && scopes[1]() === "b"); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
temporal dead zone (strict mode)
?
function(){
'use strict';
var passed = (function(){ try { qux; } catch(e) { return true; }}());
function fn() { passed &= qux === 456; }
const qux = 456;
fn();
return passed; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
let |
||||||||||
basic support
?
function(){
let foo = 123;
return (foo === 123); }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
is block-scoped
?
function(){
let bar = 123;
{ let bar = 456; }
return bar === 123; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
scope shadow resolution
?
function(){
try {
{ let bar = 456; }
let bar = 123;
return bar === 123;
} catch(e) {
return false;
} }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
cannot be in statements
?
function(){
let bar = 1;
try {
Function("if(true) let baz = 1;")();
} catch(e) {
return true;
} }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
for loop statement scope
?
function(){
let baz = 1;
for(let baz = 0; false;) {}
return baz === 1; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
temporal dead zone
?
function(){
var passed = (function(){ try { qux; } catch(e) { return true; }}());
function fn() { passed &= qux === 456; }
let qux = 456;
fn();
return passed; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
for/for-in loop iteration scope
?
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; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
for-in loop binding shadowing parameter
?
function(){
try {
Function("function f(e) { for (let e in {}) e }");
return true;
} catch(e) {
return false;
} }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
basic support (strict mode)
?
function(){
'use strict';
let foo = 123;
return (foo === 123); }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
is block-scoped (strict mode)
?
function(){
'use strict';
let bar = 123;
{ let bar = 456; }
return bar === 123; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
scope shadow resolution (strict mode)
?
function(){
'use strict';
try {
{ let bar = 456; }
let bar = 123;
return bar === 123;
} catch(e) {
return false;
} }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
cannot be in statements (strict mode)
?
function(){
'use strict';
let bar = 1;
try {
Function("'use strict'; if(true) let baz = 1;")();
} catch(e) {
return true;
} }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
for loop statement scope (strict mode)
?
function(){
'use strict';
let baz = 1;
for(let baz = 0; false;) {}
return baz === 1; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
temporal dead zone (strict mode)
?
function(){
'use strict';
var passed = (function(){ try { qux; } catch(e) { return true; }}());
function fn() { passed &= qux === 456; }
let qux = 456;
fn();
return passed; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
for/for-in loop iteration scope (strict mode)
?
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; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
for-in loop binding shadowing parameter (strict mode)
?
function(){
try {
Function("'use strict'; function f(e) { for (let e in {}) e }");
return true;
} catch(e) {
return false;
} }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
|
||||||||||
block-level function declaration
?
function(){
'use strict';
if (f() !== 1) return false;
function f() { return 1; }
{
if (f() !== 2) return false;
function f() { return 2; }
if (f() !== 2) return false;
}
if (f() !== 1) return false;
return true; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
arrow functions |
||||||||||
0 parameters
?
function(){
return (() => 5)() === 5; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
1 parameter, no brackets
?
function(){
var b = x => x + "foo";
return (b("fee fie foe ") === "fee fie foe foo"); }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
multiple parameters
?
function(){
var c = (v, w, x, y, z) => "" + v + w + x + y + z;
return (c(6, 5, 4, 3, 2) === "65432"); }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
lexical "this" binding
?
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"; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
"this" unchanged by call or apply
?
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"; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
can't be bound, can be curried
?
function(){
var d = { x : "bar", y : function() { return z => this.x + z; }};
var e = { x : "baz" };
return d.y().bind(e, "ley")() === "barley"; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
lexical "arguments" binding
?
function(){
var f = (function() { return z => arguments[0]; }(5));
return f(6) === 5; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
no line break between params and =>
?
function(){
return (() => {
try { Function("x\n => 2")(); } catch(e) { return true; }
})(); }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
correct precedence
?
function(){
return (() => {
try { Function("0 || () => 2")(); } catch(e) { return true; }
})(); }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
no "prototype" property
?
function(){
var a = () => 5;
return !a.hasOwnProperty("prototype"); }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
lexical "super" binding in constructors
?
function(){
var received;
class B {
constructor (arg) {
received = arg;
}
}
class C extends B {
constructor () {
var callSuper = () => super('foo');
callSuper();
}
}
return new C instanceof C && received === 'foo' }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
lexical "super" binding in methods
?
function(){
class B {
qux() {
return "quux";
}
}
class C extends B {
baz() {
return x => super.qux();
}
}
var arrow = new C().baz();
return arrow() === "quux"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
lexical "new.target" binding
?
function(){
function C() {
return x => new.target;
}
return new C()() === C && C()() === void undefined; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
class |
||||||||||
class statement
?
function(){
class C {}
return typeof C === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
is block-scoped
?
function(){
class C {}
var c1 = C;
{
class C {}
var c2 = C;
}
return C === c1; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
class expression
?
function(){
return typeof class C {} === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
anonymous class
?
function(){
return typeof class {} === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
constructor
?
function(){
class C {
constructor() { this.x = 1; }
}
return C.prototype.constructor === C
&& new C().x === 1; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
prototype methods
?
function(){
class C {
method() { return 2; }
}
return typeof C.prototype.method === "function"
&& new C().method() === 2; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
string-keyed methods
?
function(){
class C {
"foo bar"() { return 2; }
}
return typeof C.prototype["foo bar"] === "function"
&& new C()["foo bar"]() === 2; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
computed prototype methods
?
function(){
var foo = "method";
class C {
[foo]() { return 2; }
}
return typeof C.prototype.method === "function"
&& new C().method() === 2; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
optional semicolons
?
function(){
class C {
;
method() { return 2; };
method2() { return 2; }
method3() { return 2; };
}
return typeof C.prototype.method === "function"
&& typeof C.prototype.method2 === "function"
&& typeof C.prototype.method3 === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
static methods
?
function(){
class C {
static method() { return 3; }
}
return typeof C.method === "function"
&& C.method() === 3; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
computed static methods
?
function(){
var foo = "method";
class C {
static [foo]() { return 3; }
}
return typeof C.method === "function"
&& C.method() === 3; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
accessor properties
?
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; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
computed accessor properties
?
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; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
static accessor properties
?
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; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
computed static accessor properties
?
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; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
class name is lexically scoped
?
function(){
class C {
method() { return typeof C === "function"; }
}
var M = C.prototype.method;
C = void undefined;
return C === void undefined && M(); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
computed names, temporal dead zone
?
function(){
try {
var B = class C {
[C](){}
}
} catch(e) {
return true;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
methods aren't enumerable
?
function(){
class C {
foo() {}
static bar() {}
}
return !C.prototype.propertyIsEnumerable("foo") && !C.propertyIsEnumerable("bar"); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
implicit strict mode
?
function(){
class C {
static method() { return this === void undefined; }
}
return (0,C.method)(); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
constructor requires new
?
function(){
class C {}
try {
C();
}
catch(e) {
return true;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
extends
?
function(){
class B {}
class C extends B {}
return new C() instanceof B
&& B.isPrototypeOf(C); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
extends expressions
?
function(){
var B;
class C extends (B = class {}) {}
return new C() instanceof B
&& B.isPrototypeOf(C); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
extends null
?
function(){
class C extends null {
constructor() { return Object.create(null); }
}
return Function.prototype.isPrototypeOf(C)
&& Object.getPrototypeOf(C.prototype) === null; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
new.target
?
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; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
super |
||||||||||
statement in constructors
?
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; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
expression in constructors
?
function(){
class B {
constructor(a) { return ["foo" + a]; }
}
class C extends B {
constructor(a) { return super("bar" + a); }
}
return new C("baz")[0] === "foobarbaz"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
in methods, property access
?
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"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
in methods, method calls
?
function(){
class B {
qux(a) { return "foo" + a; }
}
class C extends B {
qux(a) { return super.qux("bar" + a); }
}
return new C().qux("baz") === "foobarbaz"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
method calls use correct "this" binding
?
function(){
class B {
qux(a) { return this.foo + a; }
}
class C extends B {
qux(a) { return super.qux("bar" + a); }
}
var obj = new C();
obj.foo = "foo";
return obj.qux("baz") === "foobarbaz"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
constructor calls use correct "new.target" binding
?
function(){
var passed;
class B {
constructor() { passed = (new.target === C); }
}
class C extends B {
constructor() { super(); }
}
new C();
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
is statically bound
?
function(){
class B {
qux() { return "bar"; }
}
class C extends B {
qux() { return super.qux() + this.corge; }
}
var obj = {
qux: C.prototype.qux,
corge: "ley"
};
return obj.qux() === "barley"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
super() invokes the correct constructor
?
function(){
// checks that super() is *not* a synonym of super.constructor()
var passed;
class B {
constructor() {
passed = true;
}
};
B.prototype.constructor = function () {
passed = false;
};
class C extends B { };
new C;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
generators |
||||||||||
basic functionality
?
function(){
function * generator(){
yield 5; yield 6;
};
var iterator = generator();
var item = iterator.next();
var passed = item.value === 5 && item.done === false;
item = iterator.next();
passed &= item.value === 6 && item.done === false;
item = iterator.next();
passed &= item.value === void undefined && item.done === true;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
generator function expressions
?
function(){
var generator = function * (){
yield 5; yield 6;
};
var iterator = generator();
var item = iterator.next();
var passed = item.value === 5 && item.done === false;
item = iterator.next();
passed &= item.value === 6 && item.done === false;
item = iterator.next();
passed &= item.value === void undefined && item.done === true;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No Flag |
No Flag |
No Flag |
Yes Yes |
correct "this" binding
?
function(){
function * generator(){
yield this.x; yield this.y;
};
var iterator = { g: generator, x: 5, y: 6 }.g();
var item = iterator.next();
var passed = item.value === 5 && item.done === false;
item = iterator.next();
passed &= item.value === 6 && item.done === false;
item = iterator.next();
passed &= item.value === void undefined && item.done === true;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
can't use "this" with new
?
function(){
function * generator(){
yield this.x; yield this.y;
};
try {
(new generator()).next();
}
catch (e) {
return true;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error No |
Error No |
Error No |
No No |
sending
?
function(){
var sent;
function * generator(){
sent = [yield 5, yield 6];
};
var iterator = generator();
iterator.next();
iterator.next("foo");
iterator.next("bar");
return sent[0] === "foo" && sent[1] === "bar"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
%GeneratorPrototype%
?
function(){
function * generatorFn(){}
var ownProto = Object.getPrototypeOf(generatorFn());
var passed = ownProto === generatorFn.prototype;
var sharedProto = Object.getPrototypeOf(ownProto);
passed &= sharedProto !== Object.prototype &&
sharedProto === Object.getPrototypeOf(function*(){}.prototype) &&
sharedProto.hasOwnProperty('next');
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error No |
Error No |
Error No |
No No |
%GeneratorPrototype% prototype chain
?
function(){
function * generatorFn(){}
var g = generatorFn();
var ownProto = Object.getPrototypeOf(g);
var passed = ownProto === generatorFn.prototype;
var sharedProto = Object.getPrototypeOf(ownProto);
var iterProto = Object.getPrototypeOf(sharedProto);
passed &= iterProto.hasOwnProperty(Symbol.iterator) &&
!sharedProto .hasOwnProperty(Symbol.iterator) &&
!ownProto .hasOwnProperty(Symbol.iterator) &&
g[Symbol.iterator]() === g;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
%GeneratorPrototype%.constructor
?
function(){
function * g (){}
var iterator = new g.constructor("a","b","c","yield a; yield b; yield c;")(5,6,7);
var item = iterator.next();
var passed = item.value === 5 && item.done === false;
item = iterator.next();
passed &= item.value === 6 && item.done === false;
item = iterator.next();
passed &= item.value === 7 && item.done === false;
item = iterator.next();
passed &= item.value === void undefined && item.done === true;
passed &= g.constructor === (function*(){}).constructor;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
%GeneratorPrototype%.throw
?
function(){
var passed = false;
function * generator(){
try {
yield 5; yield 6;
} catch(e) {
passed = (e === "foo");
}
};
var iterator = generator();
iterator.next();
iterator.throw("foo");
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
%GeneratorPrototype%.return
?
function(){
function * generator(){
yield 5; yield 6;
};
var iterator = generator();
var item = iterator.next();
var passed = item.value === 5 && item.done === false;
item = iterator.return("quxquux");
passed &= item.value === "quxquux" && item.done === true;
item = iterator.next();
passed &= item.value === void undefined && item.done === true;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error No |
Error No |
Error No |
No No |
yield operator precedence
?
function(){
var passed;
function * generator(){
passed = yield 0 ? true : false;
};
var iterator = generator();
iterator.next();
iterator.next(true);
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
yield *, arrays
?
function(){
var iterator = (function * generator() {
yield * [5, 6];
}());
var item = iterator.next();
var passed = item.value === 5 && item.done === false;
item = iterator.next();
passed &= item.value === 6 && item.done === false;
item = iterator.next();
passed &= item.value === void undefined && item.done === true;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
yield *, sparse arrays
?
function(){
var iterator = (function * generator() {
yield * [,,];
}());
var item = iterator.next();
var passed = item.value === void undefined && item.done === false;
item = iterator.next();
passed &= item.value === void undefined && item.done === false;
item = iterator.next();
passed &= item.value === void undefined && item.done === true;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
yield *, strings
?
function(){
var iterator = (function * generator() {
yield * "56";
}());
var item = iterator.next();
var passed = item.value === "5" && item.done === false;
item = iterator.next();
passed &= item.value === "6" && item.done === false;
item = iterator.next();
passed &= item.value === void undefined && item.done === true;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
yield *, astral plane strings
?
function(){
var iterator = (function * generator() {
yield * "𠮷𠮶";
}());
var item = iterator.next();
var passed = item.value === "𠮷" && item.done === false;
item = iterator.next();
passed &= item.value === "𠮶" && item.done === false;
item = iterator.next();
passed &= item.value === void undefined && item.done === true;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
yield *, generator instances
?
function(){
var iterator = (function * generator() {
yield * (function*(){ yield 5; yield 6; yield 7; }());
}());
var item = iterator.next();
var passed = item.value === 5 && item.done === false;
item = iterator.next();
passed &= item.value === 6 && item.done === false;
item = iterator.next();
passed &= item.value === 7 && item.done === false;
item = iterator.next();
passed &= item.value === void undefined && item.done === true;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
yield *, generic iterables
?
function(){
var iterator = (function * generator() {
yield * global.__createIterableObject([5, 6, 7]);
}());
var item = iterator.next();
var passed = item.value === 5 && item.done === false;
item = iterator.next();
passed &= item.value === 6 && item.done === false;
item = iterator.next();
passed &= item.value === 7 && item.done === false;
item = iterator.next();
passed &= item.value === void undefined && item.done === true;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
yield *, instances of iterables
?
function(){
var iterator = (function * generator() {
yield * Object.create(__createIterableObject([5, 6, 7]));
}());
var item = iterator.next();
var passed = item.value === 5 && item.done === false;
item = iterator.next();
passed &= item.value === 6 && item.done === false;
item = iterator.next();
passed &= item.value === 7 && item.done === false;
item = iterator.next();
passed &= item.value === void undefined && item.done === true;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
yield * on non-iterables is a runtime error
?
function(){
var iterator = (function * generator() {
yield * [5];
}());
var item = iterator.next();
var passed = item.value === 5 && item.done === false;
iterator = (function * generator() {
yield * 5;
}());
try {
iterator.next();
} catch (e) {
return passed;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
yield *, iterator closing
?
function(){
var closed = '';
var iter = __createIterableObject([1, 2, 3], {
'return': function(){
closed += 'a';
return {done: true};
}
});
var gen = (function* generator(){
try {
yield *iter;
} finally {
closed += 'b';
}
})();
gen.next();
gen['return']();
return closed === 'ab'; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
yield *, iterator closing via throw()
?
function(){
var closed = false;
var iter = global.__createIterableObject([1, 2, 3], {
'throw': undefined,
'return': function() {
closed = true;
return {done: true};
}
});
var gen = (function*(){
try {
yield *iter;
} catch(e){}
})();
gen.next();
gen['throw']();
return closed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
shorthand generator methods
?
function(){
var o = {
* generator() {
yield 5; yield 6;
}
};
var iterator = o.generator();
var item = iterator.next();
var passed = item.value === 5 && item.done === false;
item = iterator.next();
passed &= item.value === 6 && item.done === false;
item = iterator.next();
passed &= item.value === void undefined && item.done === true;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
string-keyed shorthand generator methods
?
function(){
var o = {
* "foo bar"() {
yield 5; yield 6;
}
};
var iterator = o["foo bar"]();
var item = iterator.next();
var passed = item.value === 5 && item.done === false;
item = iterator.next();
passed &= item.value === 6 && item.done === false;
item = iterator.next();
passed &= item.value === void undefined && item.done === true;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
computed shorthand generators
?
function(){
var garply = "generator";
var o = {
* [garply] () {
yield 5; yield 6;
}
};
var iterator = o.generator();
var item = iterator.next();
var passed = item.value === 5 && item.done === false;
item = iterator.next();
passed &= item.value === 6 && item.done === false;
item = iterator.next();
passed &= item.value === void undefined && item.done === true;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
shorthand generator methods, classes
?
function(){
class C {
* generator() {
yield 5; yield 6;
}
};
var iterator = new C().generator();
var item = iterator.next();
var passed = item.value === 5 && item.done === false;
item = iterator.next();
passed &= item.value === 6 && item.done === false;
item = iterator.next();
passed &= item.value === void undefined && item.done === true;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
computed shorthand generators, classes
?
function(){
var garply = "generator";
class C {
* [garply] () {
yield 5; yield 6;
}
}
var iterator = new C().generator();
var item = iterator.next();
var passed = item.value === 5 && item.done === false;
item = iterator.next();
passed &= item.value === 6 && item.done === false;
item = iterator.next();
passed &= item.value === void undefined && item.done === true;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
shorthand generators can't be constructors
?
function(){
class C {
* generator() {
yield 5; yield 6;
}
};
try {
Function("class D { * constructor() { return {}; } }");
} catch(e) {
return true;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
typed arrays |
||||||||||
Int8Array
?
function(){
var buffer = new ArrayBuffer(64);
var view = new Int8Array(buffer); view[0] = 0x80;
return view[0] === -0x80; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Uint8Array
?
function(){
var buffer = new ArrayBuffer(64);
var view = new Uint8Array(buffer); view[0] = 0x100;
return view[0] === 0; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Uint8ClampedArray
?
function(){
var buffer = new ArrayBuffer(64);
var view = new Uint8ClampedArray(buffer); view[0] = 0x100;
return view[0] === 0xFF; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Int16Array
?
function(){
var buffer = new ArrayBuffer(64);
var view = new Int16Array(buffer); view[0] = 0x8000;
return view[0] === -0x8000; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Uint16Array
?
function(){
var buffer = new ArrayBuffer(64);
var view = new Uint16Array(buffer); view[0] = 0x10000;
return view[0] === 0; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Int32Array
?
function(){
var buffer = new ArrayBuffer(64);
var view = new Int32Array(buffer); view[0] = 0x80000000;
return view[0] === -0x80000000; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Uint32Array
?
function(){
var buffer = new ArrayBuffer(64);
var view = new Uint32Array(buffer); view[0] = 0x100000000;
return view[0] === 0; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Float32Array
?
function(){
var buffer = new ArrayBuffer(64);
var view = new Float32Array(buffer); view[0] = 0.1;
return view[0] === 0.10000000149011612; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Float64Array
?
function(){
var buffer = new ArrayBuffer(64);
var view = new Float64Array(buffer); view[0] = 0.1;
return view[0] === 0.1; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
DataView (Int8)
?
function(){
var buffer = new ArrayBuffer(64);
var view = new DataView(buffer);
view.setInt8 (0, 0x80);
return view.getInt8(0) === -0x80; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
DataView (Uint8)
?
function(){
var buffer = new ArrayBuffer(64);
var view = new DataView(buffer);
view.setUint8(0, 0x100);
return view.getUint8(0) === 0; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
DataView (Int16)
?
function(){
var buffer = new ArrayBuffer(64);
var view = new DataView(buffer);
view.setInt16(0, 0x8000);
return view.getInt16(0) === -0x8000; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
DataView (Uint16)
?
function(){
var buffer = new ArrayBuffer(64);
var view = new DataView(buffer);
view.setUint16(0, 0x10000);
return view.getUint16(0) === 0; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
DataView (Int32)
?
function(){
var buffer = new ArrayBuffer(64);
var view = new DataView(buffer);
view.setInt32(0, 0x80000000);
return view.getInt32(0) === -0x80000000; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
DataView (Uint32)
?
function(){
var buffer = new ArrayBuffer(64);
var view = new DataView(buffer);
view.setUint32(0, 0x100000000);
return view.getUint32(0) === 0; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
DataView (Float32)
?
function(){
var buffer = new ArrayBuffer(64);
var view = new DataView(buffer);
view.setFloat32(0, 0.1);
return view.getFloat32(0) === 0.10000000149011612; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
DataView (Float64)
?
function(){
var buffer = new ArrayBuffer(64);
var view = new DataView(buffer);
view.setFloat64(0, 0.1);
return view.getFloat64(0) === 0.1; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
ArrayBuffer[Symbol.species]
?
function(){
return typeof ArrayBuffer[Symbol.species] === 'function'; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
constructors require new
?
function(){
var buffer = new ArrayBuffer(64);
var constructors = [
'ArrayBuffer',
'DataView',
'Int8Array',
'Uint8Array',
'Uint8ClampedArray',
'Int16Array',
'Uint16Array',
'Int32Array',
'Uint32Array',
'Float32Array',
'Float64Array'
];
return constructors.every(function (constructor) {
try {
if (constructor in global) {
global[constructor](constructor === "ArrayBuffer" ? 64 : buffer);
}
return false;
} catch(e) {
return true;
}
}); }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
constructors accept generic iterables
?
function(){
var constructors = [
'Int8Array',
'Uint8Array',
'Uint8ClampedArray',
'Int16Array',
'Uint16Array',
'Int32Array',
'Uint32Array',
'Float32Array',
'Float64Array'
];
for(var i = 0; i < constructors.length; i++){
var arr = new global[constructors[i]](__createIterableObject([1, 2, 3]));
if(arr.length !== 3 || arr[0] !== 1 || arr[1] !== 2 || arr[2] !== 3)return false;
}
return true; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
correct prototype chains
?
function(){
var constructors = [
'Int8Array',
'Uint8Array',
'Uint8ClampedArray',
'Int16Array',
'Uint16Array',
'Int32Array',
'Uint32Array',
'Float32Array',
'Float64Array'
];
var constructor = Object.getPrototypeOf(Int8Array);
var prototype = Object.getPrototypeOf(Int8Array.prototype);
if(constructor === Function.prototype || prototype === Object.prototype)return false;
for(var i = 0; i < constructors.length; i+=1) {
if (!(constructors[i] in global
&& Object.getPrototypeOf(global[constructors[i]]) === constructor
&& Object.getPrototypeOf(global[constructors[i]].prototype) === prototype
&& Object.getOwnPropertyNames(global[constructors[i]].prototype).sort() + ''
=== "BYTES_PER_ELEMENT,constructor")) {
return false;
}
}
return true; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
%TypedArray%.from
?
function(){
return typeof Int8Array.from === "function" &&
typeof Uint8Array.from === "function" &&
typeof Uint8ClampedArray.from === "function" &&
typeof Int16Array.from === "function" &&
typeof Uint16Array.from === "function" &&
typeof Int32Array.from === "function" &&
typeof Uint32Array.from === "function" &&
typeof Float32Array.from === "function" &&
typeof Float64Array.from === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
%TypedArray%.of
?
function(){
return typeof Int8Array.of === "function" &&
typeof Uint8Array.of === "function" &&
typeof Uint8ClampedArray.of === "function" &&
typeof Int16Array.of === "function" &&
typeof Uint16Array.of === "function" &&
typeof Int32Array.of === "function" &&
typeof Uint32Array.of === "function" &&
typeof Float32Array.of === "function" &&
typeof Float64Array.of === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
%TypedArray%.prototype.subarray
?
function(){
return typeof Int8Array.prototype.subarray === "function" &&
typeof Uint8Array.prototype.subarray === "function" &&
typeof Uint8ClampedArray.prototype.subarray === "function" &&
typeof Int16Array.prototype.subarray === "function" &&
typeof Uint16Array.prototype.subarray === "function" &&
typeof Int32Array.prototype.subarray === "function" &&
typeof Uint32Array.prototype.subarray === "function" &&
typeof Float32Array.prototype.subarray === "function" &&
typeof Float64Array.prototype.subarray === "function"; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
%TypedArray%.prototype.join
?
function(){
return typeof Int8Array.prototype.join === "function" &&
typeof Uint8Array.prototype.join === "function" &&
typeof Uint8ClampedArray.prototype.join === "function" &&
typeof Int16Array.prototype.join === "function" &&
typeof Uint16Array.prototype.join === "function" &&
typeof Int32Array.prototype.join === "function" &&
typeof Uint32Array.prototype.join === "function" &&
typeof Float32Array.prototype.join === "function" &&
typeof Float64Array.prototype.join === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype.indexOf
?
function(){
return typeof Int8Array.prototype.indexOf === "function" &&
typeof Uint8Array.prototype.indexOf === "function" &&
typeof Uint8ClampedArray.prototype.indexOf === "function" &&
typeof Int16Array.prototype.indexOf === "function" &&
typeof Uint16Array.prototype.indexOf === "function" &&
typeof Int32Array.prototype.indexOf === "function" &&
typeof Uint32Array.prototype.indexOf === "function" &&
typeof Float32Array.prototype.indexOf === "function" &&
typeof Float64Array.prototype.indexOf === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype.lastIndexOf
?
function(){
return typeof Int8Array.prototype.lastIndexOf === "function" &&
typeof Uint8Array.prototype.lastIndexOf === "function" &&
typeof Uint8ClampedArray.prototype.lastIndexOf === "function" &&
typeof Int16Array.prototype.lastIndexOf === "function" &&
typeof Uint16Array.prototype.lastIndexOf === "function" &&
typeof Int32Array.prototype.lastIndexOf === "function" &&
typeof Uint32Array.prototype.lastIndexOf === "function" &&
typeof Float32Array.prototype.lastIndexOf === "function" &&
typeof Float64Array.prototype.lastIndexOf === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype.slice
?
function(){
return typeof Int8Array.prototype.slice === "function" &&
typeof Uint8Array.prototype.slice === "function" &&
typeof Uint8ClampedArray.prototype.slice === "function" &&
typeof Int16Array.prototype.slice === "function" &&
typeof Uint16Array.prototype.slice === "function" &&
typeof Int32Array.prototype.slice === "function" &&
typeof Uint32Array.prototype.slice === "function" &&
typeof Float32Array.prototype.slice === "function" &&
typeof Float64Array.prototype.slice === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype.every
?
function(){
return typeof Int8Array.prototype.every === "function" &&
typeof Uint8Array.prototype.every === "function" &&
typeof Uint8ClampedArray.prototype.every === "function" &&
typeof Int16Array.prototype.every === "function" &&
typeof Uint16Array.prototype.every === "function" &&
typeof Int32Array.prototype.every === "function" &&
typeof Uint32Array.prototype.every === "function" &&
typeof Float32Array.prototype.every === "function" &&
typeof Float64Array.prototype.every === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype.filter
?
function(){
return typeof Int8Array.prototype.filter === "function" &&
typeof Uint8Array.prototype.filter === "function" &&
typeof Uint8ClampedArray.prototype.filter === "function" &&
typeof Int16Array.prototype.filter === "function" &&
typeof Uint16Array.prototype.filter === "function" &&
typeof Int32Array.prototype.filter === "function" &&
typeof Uint32Array.prototype.filter === "function" &&
typeof Float32Array.prototype.filter === "function" &&
typeof Float64Array.prototype.filter === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype.forEach
?
function(){
return typeof Int8Array.prototype.forEach === "function" &&
typeof Uint8Array.prototype.forEach === "function" &&
typeof Uint8ClampedArray.prototype.forEach === "function" &&
typeof Int16Array.prototype.forEach === "function" &&
typeof Uint16Array.prototype.forEach === "function" &&
typeof Int32Array.prototype.forEach === "function" &&
typeof Uint32Array.prototype.forEach === "function" &&
typeof Float32Array.prototype.forEach === "function" &&
typeof Float64Array.prototype.forEach === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype.map
?
function(){
return typeof Int8Array.prototype.map === "function" &&
typeof Uint8Array.prototype.map === "function" &&
typeof Uint8ClampedArray.prototype.map === "function" &&
typeof Int16Array.prototype.map === "function" &&
typeof Uint16Array.prototype.map === "function" &&
typeof Int32Array.prototype.map === "function" &&
typeof Uint32Array.prototype.map === "function" &&
typeof Float32Array.prototype.map === "function" &&
typeof Float64Array.prototype.map === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype.reduce
?
function(){
return typeof Int8Array.prototype.reduce === "function" &&
typeof Uint8Array.prototype.reduce === "function" &&
typeof Uint8ClampedArray.prototype.reduce === "function" &&
typeof Int16Array.prototype.reduce === "function" &&
typeof Uint16Array.prototype.reduce === "function" &&
typeof Int32Array.prototype.reduce === "function" &&
typeof Uint32Array.prototype.reduce === "function" &&
typeof Float32Array.prototype.reduce === "function" &&
typeof Float64Array.prototype.reduce === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype.reduceRight
?
function(){
return typeof Int8Array.prototype.reduceRight === "function" &&
typeof Uint8Array.prototype.reduceRight === "function" &&
typeof Uint8ClampedArray.prototype.reduceRight === "function" &&
typeof Int16Array.prototype.reduceRight === "function" &&
typeof Uint16Array.prototype.reduceRight === "function" &&
typeof Int32Array.prototype.reduceRight === "function" &&
typeof Uint32Array.prototype.reduceRight === "function" &&
typeof Float32Array.prototype.reduceRight === "function" &&
typeof Float64Array.prototype.reduceRight === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype.reverse
?
function(){
return typeof Int8Array.prototype.reverse === "function" &&
typeof Uint8Array.prototype.reverse === "function" &&
typeof Uint8ClampedArray.prototype.reverse === "function" &&
typeof Int16Array.prototype.reverse === "function" &&
typeof Uint16Array.prototype.reverse === "function" &&
typeof Int32Array.prototype.reverse === "function" &&
typeof Uint32Array.prototype.reverse === "function" &&
typeof Float32Array.prototype.reverse === "function" &&
typeof Float64Array.prototype.reverse === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype.some
?
function(){
return typeof Int8Array.prototype.some === "function" &&
typeof Uint8Array.prototype.some === "function" &&
typeof Uint8ClampedArray.prototype.some === "function" &&
typeof Int16Array.prototype.some === "function" &&
typeof Uint16Array.prototype.some === "function" &&
typeof Int32Array.prototype.some === "function" &&
typeof Uint32Array.prototype.some === "function" &&
typeof Float32Array.prototype.some === "function" &&
typeof Float64Array.prototype.some === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype.sort
?
function(){
return typeof Int8Array.prototype.sort === "function" &&
typeof Uint8Array.prototype.sort === "function" &&
typeof Uint8ClampedArray.prototype.sort === "function" &&
typeof Int16Array.prototype.sort === "function" &&
typeof Uint16Array.prototype.sort === "function" &&
typeof Int32Array.prototype.sort === "function" &&
typeof Uint32Array.prototype.sort === "function" &&
typeof Float32Array.prototype.sort === "function" &&
typeof Float64Array.prototype.sort === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype.copyWithin
?
function(){
return typeof Int8Array.prototype.copyWithin === "function" &&
typeof Uint8Array.prototype.copyWithin === "function" &&
typeof Uint8ClampedArray.prototype.copyWithin === "function" &&
typeof Int16Array.prototype.copyWithin === "function" &&
typeof Uint16Array.prototype.copyWithin === "function" &&
typeof Int32Array.prototype.copyWithin === "function" &&
typeof Uint32Array.prototype.copyWithin === "function" &&
typeof Float32Array.prototype.copyWithin === "function" &&
typeof Float64Array.prototype.copyWithin === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype.find
?
function(){
return typeof Int8Array.prototype.find === "function" &&
typeof Uint8Array.prototype.find === "function" &&
typeof Uint8ClampedArray.prototype.find === "function" &&
typeof Int16Array.prototype.find === "function" &&
typeof Uint16Array.prototype.find === "function" &&
typeof Int32Array.prototype.find === "function" &&
typeof Uint32Array.prototype.find === "function" &&
typeof Float32Array.prototype.find === "function" &&
typeof Float64Array.prototype.find === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype.findIndex
?
function(){
return typeof Int8Array.prototype.findIndex === "function" &&
typeof Uint8Array.prototype.findIndex === "function" &&
typeof Uint8ClampedArray.prototype.findIndex === "function" &&
typeof Int16Array.prototype.findIndex === "function" &&
typeof Uint16Array.prototype.findIndex === "function" &&
typeof Int32Array.prototype.findIndex === "function" &&
typeof Uint32Array.prototype.findIndex === "function" &&
typeof Float32Array.prototype.findIndex === "function" &&
typeof Float64Array.prototype.findIndex === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype.fill
?
function(){
return typeof Int8Array.prototype.fill === "function" &&
typeof Uint8Array.prototype.fill === "function" &&
typeof Uint8ClampedArray.prototype.fill === "function" &&
typeof Int16Array.prototype.fill === "function" &&
typeof Uint16Array.prototype.fill === "function" &&
typeof Int32Array.prototype.fill === "function" &&
typeof Uint32Array.prototype.fill === "function" &&
typeof Float32Array.prototype.fill === "function" &&
typeof Float64Array.prototype.fill === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype.keys
?
function(){
return typeof Int8Array.prototype.keys === "function" &&
typeof Uint8Array.prototype.keys === "function" &&
typeof Uint8ClampedArray.prototype.keys === "function" &&
typeof Int16Array.prototype.keys === "function" &&
typeof Uint16Array.prototype.keys === "function" &&
typeof Int32Array.prototype.keys === "function" &&
typeof Uint32Array.prototype.keys === "function" &&
typeof Float32Array.prototype.keys === "function" &&
typeof Float64Array.prototype.keys === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype.values
?
function(){
return typeof Int8Array.prototype.values === "function" &&
typeof Uint8Array.prototype.values === "function" &&
typeof Uint8ClampedArray.prototype.values === "function" &&
typeof Int16Array.prototype.values === "function" &&
typeof Uint16Array.prototype.values === "function" &&
typeof Int32Array.prototype.values === "function" &&
typeof Uint32Array.prototype.values === "function" &&
typeof Float32Array.prototype.values === "function" &&
typeof Float64Array.prototype.values === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype.entries
?
function(){
return typeof Int8Array.prototype.entries === "function" &&
typeof Uint8Array.prototype.entries === "function" &&
typeof Uint8ClampedArray.prototype.entries === "function" &&
typeof Int16Array.prototype.entries === "function" &&
typeof Uint16Array.prototype.entries === "function" &&
typeof Int32Array.prototype.entries === "function" &&
typeof Uint32Array.prototype.entries === "function" &&
typeof Float32Array.prototype.entries === "function" &&
typeof Float64Array.prototype.entries === "function"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
%TypedArray%.prototype[Symbol.iterator]
?
function(){
return typeof Int8Array.prototype[Symbol.iterator] === "function" &&
typeof Uint8Array.prototype[Symbol.iterator] === "function" &&
typeof Uint8ClampedArray.prototype[Symbol.iterator] === "function" &&
typeof Int16Array.prototype[Symbol.iterator] === "function" &&
typeof Uint16Array.prototype[Symbol.iterator] === "function" &&
typeof Int32Array.prototype[Symbol.iterator] === "function" &&
typeof Uint32Array.prototype[Symbol.iterator] === "function" &&
typeof Float32Array.prototype[Symbol.iterator] === "function" &&
typeof Float64Array.prototype[Symbol.iterator] === "function"; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
%TypedArray%[Symbol.species]
?
function(){
return typeof Int8Array[Symbol.species] === "function" &&
typeof Uint8Array[Symbol.species] === "function" &&
typeof Uint8ClampedArray[Symbol.species] === "function" &&
typeof Int16Array[Symbol.species] === "function" &&
typeof Uint16Array[Symbol.species] === "function" &&
typeof Int32Array[Symbol.species] === "function" &&
typeof Uint32Array[Symbol.species] === "function" &&
typeof Float32Array[Symbol.species] === "function" &&
typeof Float64Array[Symbol.species] === "function"; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error Flag |
Yes Yes |
Map |
||||||||||
basic functionality
?
function(){
var key = {};
var map = new Map();
map.set(key, 123);
return map.has(key) && map.get(key) === 123; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
constructor arguments
?
function(){
var key1 = {};
var key2 = {};
var map = new Map([[key1, 123], [key2, 456]]);
return map.has(key1) && map.get(key1) === 123 &&
map.has(key2) && map.get(key2) === 456; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
constructor requires new
?
function(){
new Map();
try {
Map();
return false;
} catch(e) {
return true;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
constructor accepts null
?
function(){
new Map(null);
return true; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
constructor invokes set
?
function(){
var passed = false;
var _set = Map.prototype.set;
Map.prototype.set = function(k, v) {
passed = true;
};
new Map([ [1, 2] ]);
Map.prototype.set = _set;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
iterator closing
?
function(){
var closed = false;
var iter = global.__createIterableObject([1, 2, 3], {
'return': function(){ closed = true; return {}; }
});
try {
new Map(iter);
} catch(e){}
return closed; }
|
No No |
No No |
No No |
No No |
No Flag |
No Flag |
No Flag |
No Flag |
No Flag |
Yes Yes |
Map.prototype.set returns this
?
function(){
var map = new Map();
return map.set(0, 0) === map; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
-0 key converts to +0
?
function(){
var map = new Map();
map.set(-0, "foo");
var k;
map.forEach(function (value, key) {
k = 1 / key;
});
return k === Infinity && map.get(+0) === "foo"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Map.prototype.size
?
function(){
var key = {};
var map = new Map();
map.set(key, 123);
return map.size === 1; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Map.prototype.delete
?
function(){
return typeof Map.prototype.delete === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Map.prototype.clear
?
function(){
return typeof Map.prototype.clear === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Map.prototype.forEach
?
function(){
return typeof Map.prototype.forEach === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Map.prototype.keys
?
function(){
return typeof Map.prototype.keys === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Map.prototype.values
?
function(){
return typeof Map.prototype.values === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Map.prototype.entries
?
function(){
return typeof Map.prototype.entries === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Map.prototype[Symbol.iterator]
?
function(){
return typeof Map.prototype[Symbol.iterator] === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Map.prototype isn't an instance
?
function(){
new Map();
var obj = {};
try {
Map.prototype.has(obj);
}
catch(e) {
return true;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Map iterator prototype chain
?
function(){
// Iterator instance
var iterator = new Map()[Symbol.iterator]();
// %MapIteratorPrototype%
var proto1 = Object.getPrototypeOf(iterator);
// %IteratorPrototype%
var proto2 = Object.getPrototypeOf(proto1);
return proto2.hasOwnProperty(Symbol.iterator) &&
!proto1 .hasOwnProperty(Symbol.iterator) &&
!iterator .hasOwnProperty(Symbol.iterator) &&
iterator[Symbol.iterator]() === iterator; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
Map[Symbol.species]
?
function(){
var prop = Object.getOwnPropertyDescriptor(Map, Symbol.species);
return 'get' in prop && Map[Symbol.species] === Map; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Yes Yes |
Set |
||||||||||
basic functionality
?
function(){
var obj = {};
var set = new Set();
set.add(123);
set.add(123);
return set.has(123); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
constructor arguments
?
function(){
var obj1 = {};
var obj2 = {};
var set = new Set([obj1, obj2]);
return set.has(obj1) && set.has(obj2); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
constructor requires new
?
function(){
new Set();
try {
Set();
return false;
} catch(e) {
return true;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
constructor accepts null
?
function(){
new Set(null);
return true; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
constructor invokes add
?
function(){
var passed = false;
var _add = Set.prototype.add;
Set.prototype.add = function(v) {
passed = true;
};
new Set([1]);
Set.prototype.add = _add;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
iterator closing
?
function(){
var closed = false;
var iter = global.__createIterableObject([1, 2, 3], {
'return': function(){ closed = true; return {}; }
});
var add = Set.prototype.add;
Set.prototype.add = function(){ throw 0 };
try {
new Set(iter);
} catch(e){}
Set.prototype.add = add;
return closed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Set.prototype.add returns this
?
function(){
var set = new Set();
return set.add(0) === set; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
-0 key converts to +0
?
function(){
var set = new Set();
set.add(-0);
var k;
set.forEach(function (value) {
k = 1 / value;
});
return k === Infinity && set.has(+0); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Set.prototype.size
?
function(){
var obj = {};
var set = new Set();
set.add(123);
set.add(123);
set.add(456);
return set.size === 2; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Set.prototype.delete
?
function(){
return typeof Set.prototype.delete === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Set.prototype.clear
?
function(){
return typeof Set.prototype.clear === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Set.prototype.forEach
?
function(){
return typeof Set.prototype.forEach === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Set.prototype.keys
?
function(){
return typeof Set.prototype.keys === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Set.prototype.values
?
function(){
return typeof Set.prototype.values === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Set.prototype.entries
?
function(){
return typeof Set.prototype.entries === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Set.prototype[Symbol.iterator]
?
function(){
return typeof Set.prototype[Symbol.iterator] === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Set.prototype isn't an instance
?
function(){
new Set();
var obj = {};
try {
Set.prototype.has(obj);
}
catch(e) {
return true;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Set iterator prototype chain
?
function(){
// Iterator instance
var iterator = new Set()[Symbol.iterator]();
// %SetIteratorPrototype%
var proto1 = Object.getPrototypeOf(iterator);
// %IteratorPrototype%
var proto2 = Object.getPrototypeOf(proto1);
return proto2.hasOwnProperty(Symbol.iterator) &&
!proto1 .hasOwnProperty(Symbol.iterator) &&
!iterator .hasOwnProperty(Symbol.iterator) &&
iterator[Symbol.iterator]() === iterator; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
Set[Symbol.species]
?
function(){
var prop = Object.getOwnPropertyDescriptor(Set, Symbol.species);
return 'get' in prop && Set[Symbol.species] === Set; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Yes Yes |
WeakMap |
||||||||||
basic functionality
?
function(){
var key = {};
var weakmap = new WeakMap();
weakmap.set(key, 123);
return weakmap.has(key) && weakmap.get(key) === 123; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
constructor arguments
?
function(){
var key1 = {};
var key2 = {};
var weakmap = new WeakMap([[key1, 123], [key2, 456]]);
return weakmap.has(key1) && weakmap.get(key1) === 123 &&
weakmap.has(key2) && weakmap.get(key2) === 456; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
constructor requires new
?
function(){
new WeakMap();
try {
WeakMap();
return false;
} catch(e) {
return true;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
constructor accepts null
?
function(){
new WeakMap(null);
return true; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
constructor invokes set
?
function(){
var passed = false;
var _set = WeakMap.prototype.set;
WeakMap.prototype.set = function(k, v) {
passed = true;
};
new WeakMap([ [{ }, 42] ]);
WeakMap.prototype.set = _set;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
frozen objects as keys
?
function(){
var f = Object.freeze({});
var m = new WeakMap;
m.set(f, 42);
return m.get(f) === 42; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
iterator closing
?
function(){
var closed = false;
var iter = global.__createIterableObject([1, 2, 3], {
'return': function(){ closed = true; return {}; }
});
try {
new WeakMap(iter);
} catch(e){}
return closed; }
|
No No |
No No |
No No |
No No |
No Flag |
No Flag |
No Flag |
No Flag |
No Flag |
Yes Yes |
WeakMap.prototype.set returns this
?
function(){
var weakmap = new WeakMap();
var key = {};
return weakmap.set(key, 0) === weakmap; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
WeakMap.prototype.delete
?
function(){
return typeof WeakMap.prototype.delete === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
no WeakMap.prototype.clear method
?
function(){
if (!("clear" in WeakMap.prototype)) {
return true;
}
var m = new WeakMap();
var key = {};
m.set(key, 2);
m.clear();
return m.has(key); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
.has, .get and .delete methods accept primitives
?
function(){
var m = new WeakMap;
return m.has(1) === false
&& m.get(1) === void undefined
&& m.delete(1) === false; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
WeakMap.prototype isn't an instance
?
function(){
new WeakMap();
var obj = {};
try {
WeakMap.prototype.has(obj);
}
catch(e) {
return true;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
WeakSet |
||||||||||
basic functionality
?
function(){
var obj1 = {};
var weakset = new WeakSet();
weakset.add(obj1);
weakset.add(obj1);
return weakset.has(obj1); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
constructor arguments
?
function(){
var obj1 = {}, obj2 = {};
var weakset = new WeakSet([obj1, obj2]);
return weakset.has(obj1) && weakset.has(obj2); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
constructor requires new
?
function(){
new WeakSet();
try {
WeakSet();
return false;
} catch(e) {
return true;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
constructor accepts null
?
function(){
new WeakSet(null);
return true; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
constructor invokes add
?
function(){
var passed = false;
var _add = WeakSet.prototype.add;
WeakSet.prototype.add = function(v) {
passed = true;
};
new WeakSet([ { } ]);
WeakSet.prototype.add = _add;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
iterator closing
?
function(){
var closed = false;
var iter = global.__createIterableObject([1, 2, 3], {
'return': function(){ closed = true; return {}; }
});
try {
new WeakSet(iter);
} catch(e){}
return closed; }
|
No No |
No No |
No No |
No No |
No Flag |
No Flag |
No Flag |
No Flag |
No Flag |
Yes Yes |
WeakSet.prototype.add returns this
?
function(){
var weakset = new WeakSet();
var obj = {};
return weakset.add(obj) === weakset; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
WeakSet.prototype.delete
?
function(){
return typeof WeakSet.prototype.delete === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
no WeakSet.prototype.clear method
?
function(){
if (!("clear" in WeakSet.prototype)) {
return true;
}
var s = new WeakSet();
var key = {};
s.add(key);
s.clear();
return s.has(key); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
.has and .delete methods accept primitives
?
function(){
var s = new WeakSet;
return s.has(1) === false
&& s.delete(1) === false; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
WeakSet.prototype isn't an instance
?
function(){
new WeakSet();
var obj = {};
try {
WeakSet.prototype.has(obj);
}
catch(e) {
return true;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Proxy |
||||||||||
constructor requires new
?
function(){
new Proxy({}, {});
try {
Proxy({}, {});
return false;
} catch(e) {
return true;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
no "prototype" property
?
function(){
new Proxy({}, {});
return !Proxy.hasOwnProperty('prototype'); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"get" handler
?
function(){
var proxied = { };
var proxy = new Proxy(proxied, {
get: function (t, k, r) {
return t === proxied && k === "foo" && r === proxy && 5;
}
});
return proxy.foo === 5; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"get" handler, instances of proxies
?
function(){
var proxied = { };
var proxy = Object.create(new Proxy(proxied, {
get: function (t, k, r) {
return t === proxied && k === "foo" && r === proxy && 5;
}
}));
return proxy.foo === 5; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
"get" handler invariants
?
function(){
var passed = false;
var proxied = { };
var proxy = new Proxy(proxied, {
get: function () {
passed = true;
return 4;
}
});
// The value reported for a property must be the same as the value of the corresponding
// target object property if the target object property is a non-writable,
// non-configurable own data property.
Object.defineProperty(proxied, "foo", { value: 5, enumerable: true });
try {
proxy.foo;
return false;
}
catch(e) {}
// The value reported for a property must be undefined if the corresponding target
// object property is a non-configurable own accessor property that has undefined
// as its [[Get]] attribute.
Object.defineProperty(proxied, "bar",
{ set: function(){}, enumerable: true });
try {
proxy.bar;
return false;
}
catch(e) {}
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
"set" handler
?
function(){
var proxied = { };
var passed = false;
var proxy = new Proxy(proxied, {
set: function (t, k, v, r) {
passed = t === proxied && k + v === "foobar" && r === proxy;
}
});
proxy.foo = "bar";
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
"set" handler, instances of proxies
?
function(){
var proxied = { };
var passed = false;
var proxy = Object.create(new Proxy(proxied, {
set: function (t, k, v, r) {
passed = t === proxied && k + v === "foobar" && r === proxy;
}
}));
proxy.foo = "bar";
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
"set" handler invariants
?
function(){
var passed = false;
new Proxy({},{});
// Cannot change the value of a property to be different from the value of
// the corresponding target object if the corresponding target object
// property is a non-writable, non-configurable own data property.
var proxied = {};
var proxy = new Proxy(proxied, {
set: function () {
passed = true;
return true;
}
});
Object.defineProperty(proxied, "foo", { value: 2, enumerable: true });
proxy.foo = 2;
try {
proxy.foo = 4;
return false;
} catch(e) {}
// Cannot set the value of a property if the corresponding target
// object property is a non-configurable own accessor property
// that has undefined as its [[Set]] attribute.
Object.defineProperty(proxied, "bar",
{ get: function(){}, enumerable: true });
try {
proxy.bar = 2;
return false;
} catch(e) {}
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
"has" handler
?
function(){
var proxied = {};
var passed = false;
"foo" in new Proxy(proxied, {
has: function (t, k) {
passed = t === proxied && k === "foo";
}
});
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"has" handler, instances of proxies
?
function(){
var proxied = {};
var passed = false;
"foo" in Object.create(new Proxy(proxied, {
has: function (t, k) {
passed = t === proxied && k === "foo";
}
}));
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"has" handler invariants
?
function(){
var passed = false;
new Proxy({},{});
// A property cannot be reported as non-existent, if it exists as a
// non-configurable own property of the target object.
var proxied = {};
var proxy = new Proxy(proxied, {
has: function () {
passed = true;
return false;
}
});
Object.defineProperty(proxied, "foo", { value: 2, writable: true, enumerable: true });
try {
'foo' in proxy;
return false;
} catch(e) {}
// A property cannot be reported as non-existent, if it exists as an
// own property of the target object and the target object is not extensible.
proxied.bar = 2;
Object.preventExtensions(proxied);
try {
'bar' in proxy;
return false;
} catch(e) {}
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"deleteProperty" handler
?
function(){
var proxied = {};
var passed = false;
delete new Proxy(proxied, {
deleteProperty: function (t, k) {
passed = t === proxied && k === "foo";
}
}).foo;
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"deleteProperty" handler invariant
?
function(){
var passed = false;
new Proxy({},{});
// A property cannot be reported as deleted, if it exists as a non-configurable
// own property of the target object.
var proxied = {};
Object.defineProperty(proxied, "foo", { value: 2, writable: true, enumerable: true });
try {
delete new Proxy(proxied, {
deleteProperty: function () {
passed = true;
return true;
}
}).foo;
return false;
} catch(e) {}
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"getOwnPropertyDescriptor" handler
?
function(){
var proxied = {};
var fakeDesc = { value: "foo", configurable: true };
var returnedDesc = Object.getOwnPropertyDescriptor(
new Proxy(proxied, {
getOwnPropertyDescriptor: function (t, k) {
return t === proxied && k === "foo" && fakeDesc;
}
}),
"foo"
);
return (returnedDesc.value === fakeDesc.value
&& returnedDesc.configurable === fakeDesc.configurable
&& returnedDesc.writable === false
&& returnedDesc.enumerable === false); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"getOwnPropertyDescriptor" handler invariants
?
function(){
var passed = false;
new Proxy({},{});
// A property cannot be reported as non-existent, if it exists as a non-configurable
// own property of the target object.
var proxied = {};
var proxy = new Proxy(proxied, {
getOwnPropertyDescriptor: function () {
passed = true;
return undefined;
}
});
Object.defineProperty(proxied, "foo", { value: 2, writable: true, enumerable: true });
try {
Object.getOwnPropertyDescriptor(proxy, "foo");
return false;
} catch(e) {}
// A property cannot be reported as non-existent, if it exists as an own property
// of the target object and the target object is not extensible.
proxied.bar = 3;
Object.preventExtensions(proxied);
try {
Object.getOwnPropertyDescriptor(proxy, "bar");
return false;
} catch(e) {}
// A property cannot be reported as existent, if it does not exists as an own property
// of the target object and the target object is not extensible.
try {
Object.getOwnPropertyDescriptor(new Proxy(proxied, {
getOwnPropertyDescriptor: function() {
return { value: 2, configurable: true, writable: true, enumerable: true };
}}), "baz");
return false;
} catch(e) {}
// A property cannot be reported as non-configurable, if it does not exists as an own
// property of the target object or if it exists as a configurable own property of
// the target object.
try {
Object.getOwnPropertyDescriptor(new Proxy({}, {
getOwnPropertyDescriptor: function() {
return { value: 2, configurable: false, writable: true, enumerable: true };
}}), "baz");
return false;
} catch(e) {}
try {
Object.getOwnPropertyDescriptor(new Proxy({baz:1}, {
getOwnPropertyDescriptor: function() {
return { value: 1, configurable: false, writable: true, enumerable: true };
}}), "baz");
return false;
} catch(e) {}
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
"defineProperty" handler
?
function(){
var proxied = {};
var passed = false;
Object.defineProperty(
new Proxy(proxied, {
defineProperty: function (t, k, d) {
passed = t === proxied && k === "foo" && d.value === 5;
return true;
}
}),
"foo",
{ value: 5, configurable: true }
);
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"defineProperty" handler invariants
?
function(){
var passed = false;
new Proxy({},{});
// A property cannot be added, if the target object is not extensible.
var proxied = Object.preventExtensions({});
var proxy = new Proxy(proxied, {
defineProperty: function() {
passed = true;
return true;
}
});
try {
Object.defineProperty(proxy, "foo", { value: 2 });
return false;
} catch(e) {}
// A property cannot be non-configurable, unless there exists a corresponding
// non-configurable own property of the target object.
try {
Object.defineProperty(
new Proxy({ bar: true }, {
defineProperty: function () {
return true;
}
}),
"bar",
{ value: 5, configurable: false, writable: true, enumerable: true }
);
return false;
} catch(e) {}
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"getPrototypeOf" handler
?
function(){
var proxied = {};
var fakeProto = {};
var proxy = new Proxy(proxied, {
getPrototypeOf: function (t) {
return t === proxied && fakeProto;
}
});
return Object.getPrototypeOf(proxy) === fakeProto; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"getPrototypeOf" handler invariant
?
function(){
var passed = false;
new Proxy({},{});
// If the target object is not extensible, [[GetPrototypeOf]] applied to the proxy object
// must return the same value as [[GetPrototypeOf]] applied to the proxy object's target object.
try {
Object.getPrototypeOf(new Proxy(Object.preventExtensions({}), {
getPrototypeOf: function () {
passed = true;
return {};
}
}));
return false;
} catch(e) {}
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"setPrototypeOf" handler
?
function(){
var proxied = {};
var newProto = {};
var passed = false;
Object.setPrototypeOf(
new Proxy(proxied, {
setPrototypeOf: function (t, p) {
passed = t === proxied && p === newProto;
return true;
}
}),
newProto
);
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"setPrototypeOf" handler invariant
?
function(){
var passed = false;
new Proxy({},{});
Object.setPrototypeOf({},{});
// If the target object is not extensible, the argument value must be the
// same as the result of [[GetPrototypeOf]] applied to target object.
try {
Object.setPrototypeOf(
new Proxy(Object.preventExtensions({}), {
setPrototypeOf: function () {
passed = true;
return true;
}
}),{});
return false;
} catch(e) {}
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
"isExtensible" handler
?
function(){
var proxied = {};
var passed = false;
Object.isExtensible(
new Proxy(proxied, {
isExtensible: function (t) {
passed = t === proxied; return true;
}
})
);
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"isExtensible" handler invariant
?
function(){
var passed = false;
new Proxy({},{});
// [[IsExtensible]] applied to the proxy object must return the same value
// as [[IsExtensible]] applied to the proxy object's target object with the same argument.
try {
Object.isExtensible(new Proxy({}, {
isExtensible: function (t) {
passed = true;
return false;
}
}));
return false;
} catch(e) {}
try {
Object.isExtensible(new Proxy(Object.preventExtensions({}), {
isExtensible: function (t) {
return true;
}
}));
return false;
} catch(e) {}
return true; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"preventExtensions" handler
?
function(){
var proxied = {};
var passed = false;
Object.preventExtensions(
new Proxy(proxied, {
preventExtensions: function (t) {
passed = t === proxied;
return Object.preventExtensions(proxied);
}
})
);
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"preventExtensions" handler invariant
?
function(){
var passed = false;
new Proxy({},{});
// [[PreventExtensions]] applied to the proxy object only returns true
// if [[IsExtensible]] applied to the proxy object's target object is false.
try {
Object.preventExtensions(new Proxy({}, {
preventExtensions: function () {
passed = true;
return true;
}
}));
return false;
} catch(e) {}
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"ownKeys" handler
?
function(){
var proxied = {};
var passed = false;
Object.keys(
new Proxy(proxied, {
ownKeys: function (t) {
passed = t === proxied; return [];
}
})
);
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"ownKeys" handler invariant
?
function(){
var passed = false;
new Proxy({},{});
// The Type of each result List element is either String or Symbol.
try {
Object.keys(new Proxy({}, {
ownKeys: function () {
passed = true;
return [2];
}}));
return false;
} catch(e) {}
// The result List must contain the keys of all non-configurable own properties of the target object.
var proxied = {};
Object.defineProperty(proxied, "foo", { value: 2, writable: true, enumerable: true });
try {
Object.keys(new Proxy(proxied, {
ownKeys: function () {
return [];
}}));
return false;
} catch(e) {}
// If the target object is not extensible, then the result List must contain all the keys
// of the own properties of the target object and no other values.
try {
Object.keys(new Proxy(Object.preventExtensions({b:1}), {
ownKeys: function () {
return ['a'];
}}));
return false;
} catch(e) {}
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"apply" handler
?
function(){
var proxied = function(){};
var passed = false;
var host = {
method: new Proxy(proxied, {
apply: function (t, thisArg, args) {
passed = t === proxied && thisArg === host && args + "" === "foo,bar";
}
})
};
host.method("foo", "bar");
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
"apply" handler invariant
?
function(){
var passed = false;
new Proxy(function(){}, {
apply: function () { passed = true; }
})();
// A Proxy exotic object only has a [[Call]] internal method if the
// initial value of its [[ProxyTarget]] internal slot is an object
// that has a [[Call]] internal method.
try {
new Proxy({}, {
apply: function () {}
})();
return false;
} catch(e) {}
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
"construct" handler
?
function(){
var proxied = function(){};
var passed = false;
new new Proxy(proxied, {
construct: function (t, args) {
passed = t === proxied && args + "" === "foo,bar";
return {};
}
})("foo","bar");
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
"construct" handler invariants
?
function(){
var passed = false;
new Proxy({},{});
// A Proxy exotic object only has a [[Construct]] internal method if the
// initial value of its [[ProxyTarget]] internal slot is an object
// that has a [[Construct]] internal method.
try {
new new Proxy({}, {
construct: function (t, args) {
return {};
}
})();
return false;
} catch(e) {}
// The result of [[Construct]] must be an Object.
try {
new new Proxy(function(){}, {
construct: function (t, args) {
passed = true;
return 5;
}
})();
return false;
} catch(e) {}
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Proxy.revocable
?
function(){
var obj = Proxy.revocable({}, { get: function() { return 5; } });
var passed = (obj.proxy.foo === 5);
obj.revoke();
try {
obj.proxy.foo;
} catch(e) {
passed &= e instanceof TypeError;
}
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Array.isArray support
?
function(){
return Array.isArray(new Proxy([], {})); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
JSON.stringify support
?
function(){
return JSON.stringify(new Proxy(['foo'], {})) === '["foo"]'; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Reflect |
||||||||||
Reflect.get
?
function(){
return Reflect.get({ qux: 987 }, "qux") === 987; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Reflect.set
?
function(){
var obj = {};
Reflect.set(obj, "quux", 654);
return obj.quux === 654; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Reflect.has
?
function(){
return Reflect.has({ qux: 987 }, "qux"); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Reflect.deleteProperty
?
function(){
var obj = { bar: 456 };
Reflect.deleteProperty(obj, "bar");
return !("bar" in obj); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Reflect.getOwnPropertyDescriptor
?
function(){
var obj = { baz: 789 };
var desc = Reflect.getOwnPropertyDescriptor(obj, "baz");
return desc.value === 789 &&
desc.configurable && desc.writable && desc.enumerable; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Reflect.defineProperty
?
function(){
var obj = {};
Reflect.defineProperty(obj, "foo", { value: 123 });
return obj.foo === 123 &&
Reflect.defineProperty(Object.freeze({}), "foo", { value: 123 }) === false; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Reflect.getPrototypeOf
?
function(){
return Reflect.getPrototypeOf([]) === Array.prototype; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Reflect.setPrototypeOf
?
function(){
var obj = {};
Reflect.setPrototypeOf(obj, Array.prototype);
return obj instanceof Array; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Reflect.isExtensible
?
function(){
return Reflect.isExtensible({}) &&
!Reflect.isExtensible(Object.preventExtensions({})); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Reflect.preventExtensions
?
function(){
var obj = {};
Reflect.preventExtensions(obj);
return !Object.isExtensible(obj); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Reflect.ownKeys, string keys
?
function(){
var obj = Object.create({ C: true });
obj.A = true;
Object.defineProperty(obj, 'B', { value: true, enumerable: false });
return Reflect.ownKeys(obj).sort() + '' === "A,B"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Reflect.ownKeys, symbol keys
?
function(){
var s1 = Symbol(), s2 = Symbol(), s3 = Symbol();
var proto = {};
proto[s1] = true;
var obj = Object.create(proto);
obj[s2] = true;
Object.defineProperty(obj, s3, { value: true, enumerable: false });
var keys = Reflect.ownKeys(obj);
return keys.indexOf(s2) >-1 && keys.indexOf(s3) >-1 && keys.length === 2; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Reflect.apply
?
function(){
return Reflect.apply(Array.prototype.push, [1,2], [3,4,5]) === 5; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Reflect.construct
?
function(){
return Reflect.construct(function(a, b, c) {
this.qux = a + b + c;
}, ["foo", "bar", "baz"]).qux === "foobarbaz"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Reflect.construct sets new.target meta-property
?
function(){
return Reflect.construct(function(a, b, c) {
if (new.target === Object) {
this.qux = a + b + c;
}
}, ["foo", "bar", "baz"], Object).qux === "foobarbaz"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Reflect.construct creates instances from third argument
?
function(){
function F(){}
var obj = Reflect.construct(function(){ this.y = 1; }, [], F);
return obj.y === 1 && obj instanceof F; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Reflect.construct, Array subclassing
?
function(){
function F(){}
var obj = Reflect.construct(Array, [], F);
obj[2] = 'foo';
return obj.length === 3 && obj instanceof F; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Reflect.construct, RegExp subclassing
?
function(){
function F(){}
var obj = Reflect.construct(RegExp, ["baz","g"], F);
return RegExp.prototype.exec.call(obj, "foobarbaz")[0] === "baz"
&& obj.lastIndex === 9 && obj instanceof F; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Reflect.construct, Function subclassing
?
function(){
function F(){}
var obj = Reflect.construct(Function, ["return 2"], F);
return obj() === 2 && obj instanceof F; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Reflect.construct, Promise subclassing
?
function(){
function F(){}
var p1 = Reflect.construct(Promise,[function(resolve, reject) { resolve("foo"); }], F);
var p2 = Reflect.construct(Promise,[function(resolve, reject) { reject("quux"); }], F);
var score = +(p1 instanceof F && p2 instanceof F);
function thenFn(result) { score += (result === "foo"); check(); }
function catchFn(result) { score += (result === "quux"); check(); }
function shouldNotRun(result) { score = -Infinity; }
p1.then = p2.then = Promise.prototype.then;
p1.catch = p2.catch = Promise.prototype.catch;
p1.then(thenFn, shouldNotRun);
p2.then(shouldNotRun, catchFn);
p1.catch(shouldNotRun);
p2.catch(catchFn);
function check() {
if (score === 4) asyncTestPassed();
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Promise |
||||||||||
basic functionality
?
function(){
var p1 = new Promise(function(resolve, reject) { resolve("foo"); });
var p2 = new Promise(function(resolve, reject) { reject("quux"); });
var score = 0;
function thenFn(result) { score += (result === "foo"); check(); }
function catchFn(result) { score += (result === "quux"); check(); }
function shouldNotRun(result) { score = -Infinity; }
p1.then(thenFn, shouldNotRun);
p2.then(shouldNotRun, catchFn);
p1.catch(shouldNotRun);
p2.catch(catchFn);
p1.then(function() {
// Promise.prototype.then() should return a new Promise
score += p1.then() !== p1;
check();
});
function check() {
if (score === 4) asyncTestPassed();
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Yes Yes |
constructor requires new
?
function(){
new Promise(function(){});
try {
Promise(function(){});
return false;
} catch(e) {
return true;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Yes Yes |
Promise.prototype isn't an instance
?
function(){
new Promise(function(){});
try {
Promise.prototype.then(function(){});
} catch (e) {
return true;
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Yes Yes |
Promise.all
?
function(){
var fulfills = Promise.all([
new Promise(function(resolve) { setTimeout(resolve,2000,"foo"); }),
new Promise(function(resolve) { setTimeout(resolve,1000,"bar"); })
]);
var rejects = Promise.all([
new Promise(function(_, reject) { setTimeout(reject, 2000,"baz"); }),
new Promise(function(_, reject) { setTimeout(reject, 1000,"qux"); })
]);
var score = 0;
fulfills.then(function(result) { score += (result + "" === "foo,bar"); check(); });
rejects.catch(function(result) { score += (result === "qux"); check(); });
function check() {
if (score === 2) asyncTestPassed();
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Yes Yes |
Promise.all, generic iterables
?
function(){
var fulfills = Promise.all(global.__createIterableObject([
new Promise(function(resolve) { setTimeout(resolve,2000,"foo"); }),
new Promise(function(resolve) { setTimeout(resolve,1000,"bar"); })
]));
var rejects = Promise.all(global.__createIterableObject([
new Promise(function(_, reject) { setTimeout(reject, 2000,"baz"); }),
new Promise(function(_, reject) { setTimeout(reject, 1000,"qux"); })
]));
var score = 0;
fulfills.then(function(result) { score += (result + "" === "foo,bar"); check(); });
rejects.catch(function(result) { score += (result === "qux"); check(); });
function check() {
if (score === 2) asyncTestPassed();
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Yes Yes |
Promise.race
?
function(){
var fulfills = Promise.race([
new Promise(function(resolve) { setTimeout(resolve,1000,"foo"); }),
new Promise(function(_, reject) { setTimeout(reject, 2000,"bar"); })
]);
var rejects = Promise.race([
new Promise(function(_, reject) { setTimeout(reject, 1000,"baz"); }),
new Promise(function(resolve) { setTimeout(resolve,2000,"qux"); })
]);
var score = 0;
fulfills.then(function(result) { score += (result === "foo"); check(); });
rejects.catch(function(result) { score += (result === "baz"); check(); });
function check() {
if (score === 2) asyncTestPassed();
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Yes Yes |
Promise.race, generic iterables
?
function(){
var fulfills = Promise.race(global.__createIterableObject([
new Promise(function(resolve) { setTimeout(resolve,1000,"foo"); }),
new Promise(function(_, reject) { setTimeout(reject, 2000,"bar"); })
]));
var rejects = Promise.race(global.__createIterableObject([
new Promise(function(_, reject) { setTimeout(reject, 1000,"baz"); }),
new Promise(function(resolve) { setTimeout(resolve,2000,"qux"); })
]));
var score = 0;
fulfills.then(function(result) { score += (result === "foo"); check(); });
rejects.catch(function(result) { score += (result === "baz"); check(); });
function check() {
if (score === 2) asyncTestPassed();
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Yes Yes |
Promise[Symbol.species]
?
function(){
var prop = Object.getOwnPropertyDescriptor(Promise, Symbol.species);
return 'get' in prop && Promise[Symbol.species] === Promise; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Yes Yes |
Symbol |
||||||||||
basic functionality
?
function(){
var object = {};
var symbol = Symbol();
var value = {};
object[symbol] = value;
return object[symbol] === value; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
typeof support
?
function(){
return typeof Symbol() === "symbol"; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
symbol keys are hidden to pre-ES6 code
?
function(){
var object = {};
var symbol = Symbol();
object[symbol] = 1;
for (var x in object){}
var passed = !x;
if (Object.keys && Object.getOwnPropertyNames) {
passed &= Object.keys(object).length === 0
&& Object.getOwnPropertyNames(object).length === 0;
}
return passed; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Object.defineProperty support
?
function(){
var object = {};
var symbol = Symbol();
var value = {};
if (Object.defineProperty) {
Object.defineProperty(object, symbol, { value: value });
return object[symbol] === value;
}
return passed; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
symbols inherit from Symbol.prototype
?
function(){
var symbol = Symbol();
var passed = symbol.foo === void undefined;
Symbol.prototype.foo = 2;
passed &= symbol.foo === 2;
delete Symbol.prototype.foo;
return passed; }
|
Error Error |
Error Error |
Error No |
Error No |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
cannot coerce to string or number
?
function(){
var symbol = Symbol();
try {
symbol + "";
return false;
}
catch(e) {}
try {
symbol + 0;
return false;
} catch(e) {}
return true; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
can convert with String()
?
function(){
return String(Symbol("foo")) === "Symbol(foo)"; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
new Symbol() throws
?
function(){
var symbol = Symbol();
try {
new Symbol();
} catch(e) {
return true;
} }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Object(symbol)
?
function(){
var symbol = Symbol();
var symbolObject = Object(symbol);
return typeof symbolObject === "object" &&
symbolObject instanceof Symbol &&
symbolObject == symbol && // eslint-disable-line eqeqeq
symbolObject !== symbol &&
symbolObject.valueOf() === symbol; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Yes Yes |
JSON.stringify ignores symbol primitives
?
function(){
var object = { foo: Symbol() };
object[Symbol()] = 1;
var array = [Symbol()];
return JSON.stringify(object) === '{}' && JSON.stringify(array) === '[null]' && JSON.stringify(Symbol()) === void undefined; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error Flag |
Yes Yes |
JSON.stringify ignores symbol objects
?
function(){
var testSymbolObject = function (sym) {
var object = { foo: sym };
try {
// some browsers throw a TypeError when setting symbol object keys.
// this isn't part of this test, so, ignore it if so.
object[sym] = 1;
} catch (e) {} // some browsers throw a TypeError when setting symbol object keys.
var array = [sym];
return JSON.stringify(object) === '{"foo":{}}' && JSON.stringify(array) === '[{}]' && JSON.stringify(sym) === '{}';
};
var objSym = Object(Symbol());
var symNoToJSON = Object(Symbol());
Object.defineProperty(symNoToJSON, 'toJSON', { enumerable: false, value: null }); // ensure it overrides the prototype, but is not callable
return testSymbolObject(objSym) && testSymbolObject(symNoToJSON); }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
global symbol registry
?
function(){
var symbol = Symbol.for('foo');
return Symbol.for('foo') === symbol &&
Symbol.keyFor(symbol) === 'foo'; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
well-known symbols |
||||||||||
Symbol.hasInstance
?
function(){
var passed = false;
var obj = { foo: true };
var C = function(){};
Object.defineProperty(C, Symbol.hasInstance, {
value: function(inst) { passed = inst.foo; return false; }
});
obj instanceof C;
return passed; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
Symbol.isConcatSpreadable, non-spreadable array
?
function(){
var a = [], b = [];
b[Symbol.isConcatSpreadable] = false;
a = a.concat(b);
return a[0] === b; }
|
Error Error |
Error Error |
Error No |
Error No |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Symbol.isConcatSpreadable, spreadable object with poisoned getter
?
function(){
if (typeof Symbol !== 'function' || !Symbol.isConcatSpreadable) {
return null;
}
var spreadableHasPoisonedIndex = { length: Math.pow(2, 53) - 1 };
spreadableHasPoisonedIndex[Symbol.isConcatSpreadable] = true;
Object.defineProperty(spreadableHasPoisonedIndex, 0, {
get: function () { throw new SyntaxError(); }
});
try {
[].concat(spreadableHasPoisonedIndex);
return false;
} catch (e) {
return !!e && e.name === 'SyntaxError';
} }
|
No No |
No No |
No No |
No No |
No Flag |
No Flag |
No Flag |
No Flag |
No Flag |
Yes Yes |
Symbol.iterator, existence
?
function(){
return "iterator" in Symbol; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Symbol.iterator, arguments object
?
function(){
return (function() {
return typeof arguments[Symbol.iterator] === 'function'
&& Object.hasOwnProperty.call(arguments, Symbol.iterator);
}()); }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Symbol.species, existence
?
function(){
return "species" in Symbol; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Symbol.species, Array.prototype.concat
?
function(){
var obj = [];
obj.constructor = {};
obj.constructor[Symbol.species] = function() {
return { foo: 1 };
};
return Array.prototype.concat.call(obj, []).foo === 1; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
Symbol.species, Array.prototype.filter
?
function(){
var obj = [];
obj.constructor = {};
obj.constructor[Symbol.species] = function() {
return { foo: 1 };
};
return Array.prototype.filter.call(obj, Boolean).foo === 1; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
Symbol.species, Array.prototype.map
?
function(){
var obj = [];
obj.constructor = {};
obj.constructor[Symbol.species] = function() {
return { foo: 1 };
};
return Array.prototype.map.call(obj, Boolean).foo === 1; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
Symbol.species, Array.prototype.slice
?
function(){
var obj = [];
obj.constructor = {};
obj.constructor[Symbol.species] = function() {
return { foo: 1 };
};
return Array.prototype.slice.call(obj, 0).foo === 1; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
Symbol.species, Array.prototype.splice
?
function(){
var obj = [];
obj.constructor = {};
obj.constructor[Symbol.species] = function() {
return { foo: 1 };
};
return Array.prototype.splice.call(obj, 0).foo === 1; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
Symbol.species, RegExp.prototype[Symbol.split]
?
function(){
var passed = false;
var obj = { constructor: {} };
obj[Symbol.split] = RegExp.prototype[Symbol.split];
obj.constructor[Symbol.species] = function() {
passed = true;
return /./;
};
"".split(obj);
return passed; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
Symbol.species, Promise.prototype.then
?
function(){
var promise = new Promise(function(resolve){ resolve(42); });
var FakePromise1 = promise.constructor = function(exec){ exec(function(){}, function(){}); };
var FakePromise2 = function(exec){ exec(function(){}, function(){}); };
Object.defineProperty(FakePromise1, Symbol.species, {value: FakePromise2});
return promise.then(function(){}) instanceof FakePromise2; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Yes Yes |
Symbol.replace
?
function(){
var O = {};
O[Symbol.replace] = function(){
return 42;
};
return ''.replace(O) === 42; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
Symbol.search
?
function(){
var O = {};
O[Symbol.search] = function(){
return 42;
};
return ''.search(O) === 42; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
Symbol.split
?
function(){
var O = {};
O[Symbol.split] = function(){
return 42;
};
return ''.split(O) === 42; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
Symbol.match
?
function(){
var O = {};
O[Symbol.match] = function(){
return 42;
};
return ''.match(O) === 42; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
Symbol.match, RegExp constructor
?
function(){
var re = /./;
re[Symbol.match] = false;
var foo = {constructor: RegExp};
foo[Symbol.match] = true;
return RegExp(re) !== re && RegExp(foo) === foo; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
Symbol.match, String.prototype.startsWith
?
function(){
var re = /./;
try {
'/./'.startsWith(re);
} catch(e){
re[Symbol.match] = false;
return '/./'.startsWith(re);
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Yes Yes |
Symbol.match, String.prototype.endsWith
?
function(){
var re = /./;
try {
'/./'.endsWith(re);
} catch(e){
re[Symbol.match] = false;
return '/./'.endsWith(re);
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Yes Yes |
Symbol.match, String.prototype.includes
?
function(){
var re = /./;
try {
'/./'.includes(re);
} catch(e){
re[Symbol.match] = false;
return '/./'.includes(re);
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Yes Yes |
Symbol.toPrimitive
?
function(){
var a = {}, b = {}, c = {};
var passed = 0;
a[Symbol.toPrimitive] = function(hint) { passed += hint === "number"; return 0; };
b[Symbol.toPrimitive] = function(hint) { passed += hint === "string"; return 0; };
c[Symbol.toPrimitive] = function(hint) { passed += hint === "default"; return 0; };
a >= 0;
b in {};
c == 0; // eslint-disable-line eqeqeq
return passed === 3; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Yes Yes |
Symbol.toStringTag
?
function(){
var a = {};
a[Symbol.toStringTag] = "foo";
return (a + "") === "[object foo]"; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Yes Yes |
Symbol.toStringTag affects existing built-ins
?
function(){
var s = Symbol.toStringTag;
var passed = true;
[
[Array.prototype, []],
[String.prototype, ''],
[arguments, arguments],
[Function.prototype, function(){}],
[Error.prototype, new Error()],
[Boolean.prototype, true],
[Number.prototype, 2],
[Date.prototype, new Date()],
[RegExp.prototype, /./]
].forEach(function(pair){
pair[0][s] = "foo";
passed &= (Object.prototype.toString.call(pair[1]) === "[object foo]");
delete pair[0][s];
});
return passed; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Yes Yes |
Symbol.toStringTag, new built-ins
?
function(){
var passed = true;
var s = Symbol.toStringTag;
[
[String, "String Iterator"],
[Array, "Array Iterator"],
[Map, "Map Iterator"],
[Set, "Set Iterator"]
].forEach(function(pair){
var iterProto = Object.getPrototypeOf(new pair[0]()[Symbol.iterator]());
passed = passed
&& iterProto.hasOwnProperty(s)
&& iterProto[s] === pair[1];
});
passed = passed
&& Object.getPrototypeOf(function*(){})[s] === "GeneratorFunction"
&& Object.getPrototypeOf(function*(){}())[s] === "Generator"
&& Map.prototype[s] === "Map"
&& Set.prototype[s] === "Set"
&& ArrayBuffer.prototype[s] === "ArrayBuffer"
&& DataView.prototype[s] === "DataView"
&& Promise.prototype[s] === "Promise"
&& Symbol.prototype[s] === "Symbol"
&& typeof Object.getOwnPropertyDescriptor(
Object.getPrototypeOf(Int8Array).prototype, Symbol.toStringTag).get === "function";
return passed; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error No |
Error No |
Error No |
No No |
Symbol.toStringTag, misc. built-ins
?
function(){
var s = Symbol.toStringTag;
return Math[s] === "Math"
&& JSON[s] === "JSON"; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error Flag |
Yes Yes |
Symbol.unscopables
?
function(){
var a = { foo: 1, bar: 2 };
a[Symbol.unscopables] = { bar: true };
with (a) {
return foo === 1 && typeof bar === "undefined";
} }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
Object static methods |
||||||||||
Object.assign
?
function(){
var o = Object.assign({a:true}, {b:true}, {c:true});
return "a" in o && "b" in o && "c" in o; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Object.is
?
function(){
return typeof Object.is === 'function' &&
Object.is(NaN, NaN) &&
!Object.is(-0, 0); }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Object.getOwnPropertySymbols
?
function(){
var o = {};
var sym = Symbol(), sym2 = Symbol(), sym3 = Symbol();
o[sym] = true;
o[sym2] = true;
o[sym3] = true;
var result = Object.getOwnPropertySymbols(o);
return result[0] === sym
&& result[1] === sym2
&& result[2] === sym3; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Object.setPrototypeOf
?
function(){
return Object.setPrototypeOf({}, Array.prototype) instanceof Array; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
function "name" property |
||||||||||
function statements
?
function(){
function foo(){};
return foo.name === 'foo' &&
(function(){}).name === ''; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
function expressions
?
function(){
return (function foo(){}).name === 'foo' &&
(function(){}).name === ''; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
new Function
?
function(){
return (new Function).name === "anonymous"; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
bound functions
?
function(){
function foo() {};
return foo.bind({}).name === "bound foo" &&
(function(){}).bind({}).name === "bound "; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
variables (function)
?
function(){
var foo = function() {};
var bar = function baz() {};
return foo.name === "foo" && bar.name === "baz"; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
object methods (function)
?
function(){
var o = { foo: function(){}, bar: function baz(){}};
o.qux = function(){};
return o.foo.name === "foo" &&
o.bar.name === "baz" &&
o.qux.name === ""; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
accessor properties
?
function(){
var o = { get foo(){}, set foo(x){} };
var descriptor = Object.getOwnPropertyDescriptor(o, "foo");
return descriptor.get.name === "get foo" &&
descriptor.set.name === "set foo"; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
shorthand methods
?
function(){
var o = { foo(){} };
return o.foo.name === "foo"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
shorthand methods (no lexical binding)
?
function(){
var f = "foo";
return ({f() { return f; }}).f() === "foo"; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
symbol-keyed methods
?
function(){
var sym1 = Symbol("foo");
var sym2 = Symbol();
var o = {
[sym1]: function(){},
[sym2]: function(){}
};
return o[sym1].name === "[foo]" &&
o[sym2].name === ""; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
class statements
?
function(){
class foo {};
class bar { static name() {} };
return foo.name === "foo" &&
typeof bar.name === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
class expressions
?
function(){
return class foo {}.name === "foo" &&
typeof class bar { static name() {} }.name === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
variables (class)
?
function(){
var foo = class {};
var bar = class baz {};
var qux = class { static name() {} };
return foo.name === "foo" &&
bar.name === "baz" &&
typeof qux.name === "function"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
object methods (class)
?
function(){
var o = { foo: class {}, bar: class baz {}};
o.qux = class {};
return o.foo.name === "foo" &&
o.bar.name === "baz" &&
o.qux.name === ""; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
class prototype methods
?
function(){
class C { foo(){} };
return (new C).foo.name === "foo"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
class static methods
?
function(){
class C { static foo(){} };
return C.foo.name === "foo"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
isn't writable, is configurable
?
function(){
var descriptor = Object.getOwnPropertyDescriptor(function f(){},"name");
return descriptor.enumerable === false &&
descriptor.writable === false &&
descriptor.configurable === true; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
String static methods |
||||||||||
String.raw
?
function(){
return typeof String.raw === 'function'; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
String.fromCodePoint
?
function(){
return typeof String.fromCodePoint === 'function'; }
|
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
String.prototype methods |
||||||||||
String.prototype.codePointAt
?
function(){
return typeof String.prototype.codePointAt === 'function'; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
String.prototype.normalize
?
function(){
return typeof String.prototype.normalize === "function"
&& "c\u0327\u0301".normalize("NFC") === "\u1e09"
&& "\u1e09".normalize("NFD") === "c\u0327\u0301"; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
String.prototype.repeat
?
function(){
return typeof String.prototype.repeat === 'function'
&& "foo".repeat(3) === "foofoofoo"; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
String.prototype.startsWith
?
function(){
return typeof String.prototype.startsWith === 'function'
&& "foobar".startsWith("foo"); }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
String.prototype.startsWith throws on RegExp
?
function(){
try {
"a".startsWith(/./);
} catch(e) {
return typeof String.prototype.startsWith === 'function';
} }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
String.prototype.endsWith
?
function(){
return typeof String.prototype.endsWith === 'function'
&& "foobar".endsWith("bar"); }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
String.prototype.endsWith throws on RegExp
?
function(){
try {
"a".endsWith(/./);
} catch(e) {
return typeof String.prototype.endsWith === 'function';
} }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
String.prototype.includes
?
function(){
return typeof String.prototype.includes === 'function'
&& "foobar".includes("oba"); }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
String.prototype[Symbol.iterator]
?
function(){
return typeof String.prototype[Symbol.iterator] === 'function'; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
String iterator prototype chain
?
function(){
// Iterator instance
var iterator = ''[Symbol.iterator]();
// %StringIteratorPrototype%
var proto1 = Object.getPrototypeOf(iterator);
// %IteratorPrototype%
var proto2 = Object.getPrototypeOf(proto1);
return proto2.hasOwnProperty(Symbol.iterator) &&
!proto1 .hasOwnProperty(Symbol.iterator) &&
!iterator .hasOwnProperty(Symbol.iterator) &&
iterator[Symbol.iterator]() === iterator; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
RegExp.prototype properties |
||||||||||
RegExp.prototype.flags
?
function(){
return /./igm.flags === "gim" && /./.flags === ""; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
RegExp.prototype[Symbol.match]
?
function(){
return typeof RegExp.prototype[Symbol.match] === 'function'; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
RegExp.prototype[Symbol.replace]
?
function(){
return typeof RegExp.prototype[Symbol.replace] === 'function'; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
RegExp.prototype[Symbol.split]
?
function(){
return typeof RegExp.prototype[Symbol.split] === 'function'; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
RegExp.prototype[Symbol.search]
?
function(){
return typeof RegExp.prototype[Symbol.search] === 'function'; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
RegExp[Symbol.species]
?
function(){
var prop = Object.getOwnPropertyDescriptor(RegExp, Symbol.species);
return 'get' in prop && RegExp[Symbol.species] === RegExp; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Yes Yes |
Array static methods |
||||||||||
Array.from, array-like objects
?
function(){
return Array.from({ 0: "foo", 1: "bar", length: 2 }) + '' === "foo,bar"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Array.from, generator instances
?
function(){
var iterable = (function*(){ yield 1; yield 2; yield 3; }());
return Array.from(iterable) + '' === "1,2,3"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No Flag |
No Flag |
No Flag |
Yes Yes |
Array.from, generic iterables
?
function(){
var iterable = global.__createIterableObject([1, 2, 3]);
return Array.from(iterable) + '' === "1,2,3"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
No Error |
No Flag |
No Flag |
No Flag |
No Flag |
Yes Yes |
Array.from, instances of generic iterables
?
function(){
var iterable = global.__createIterableObject([1, 2, 3]);
return Array.from(Object.create(iterable)) + '' === "1,2,3"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
No Error |
No Flag |
No Flag |
No Flag |
No Flag |
Yes Yes |
Array.from map function, array-like objects
?
function(){
return Array.from({ 0: "foo", 1: "bar", length: 2 }, function(e, i) {
return e + this.baz + i;
}, { baz: "d" }) + '' === "food0,bard1"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Array.from map function, generator instances
?
function(){
var iterable = (function*(){ yield "foo"; yield "bar"; yield "bal"; }());
return Array.from(iterable, function(e, i) {
return e + this.baz + i;
}, { baz: "d" }) + '' === "food0,bard1,bald2"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No Flag |
No Flag |
No Flag |
Yes Yes |
Array.from map function, generic iterables
?
function(){
var iterable = global.__createIterableObject(["foo", "bar", "bal"]);
return Array.from(iterable, function(e, i) {
return e + this.baz + i;
}, { baz: "d" }) + '' === "food0,bard1,bald2"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
No Error |
No Flag |
No Flag |
No Flag |
No Flag |
Yes Yes |
Array.from map function, instances of iterables
?
function(){
var iterable = global.__createIterableObject(["foo", "bar", "bal"]);
return Array.from(Object.create(iterable), function(e, i) {
return e + this.baz + i;
}, { baz: "d" }) + '' === "food0,bard1,bald2"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
No Error |
No Flag |
No Flag |
No Flag |
No Flag |
Yes Yes |
Array.from, iterator closing
?
function(){
var closed = false;
var iter = global.__createIterableObject([1, 2, 3], {
'return': function(){ closed = true; return {}; }
});
try {
Array.from(iter, function() { throw 42 });
} catch(e){}
return closed; }
|
No No |
No No |
No No |
No No |
No Flag |
No Flag |
No Flag |
No Flag |
No Flag |
Yes Yes |
Array.of
?
function(){
return typeof Array.of === 'function' &&
Array.of(2)[0] === 2; }
|
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Array[Symbol.species]
?
function(){
var prop = Object.getOwnPropertyDescriptor(Array, Symbol.species);
return 'get' in prop && Array[Symbol.species] === Array; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Yes Yes |
Array.prototype methods |
||||||||||
Array.prototype.copyWithin
?
function(){
return typeof Array.prototype.copyWithin === 'function'; }
|
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Array.prototype.find
?
function(){
return typeof Array.prototype.find === 'function'; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Array.prototype.findIndex
?
function(){
return typeof Array.prototype.findIndex === 'function'; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Array.prototype.fill
?
function(){
return typeof Array.prototype.fill === 'function'; }
|
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Array.prototype.keys
?
function(){
return typeof Array.prototype.keys === 'function'; }
|
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Array.prototype.values
?
function(){
return typeof Array.prototype.values === 'function'; }
|
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Array.prototype.entries
?
function(){
return typeof Array.prototype.entries === 'function'; }
|
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Array.prototype.splice
?
function(){
if ([0, 1, 2].splice(0).length !== 3) {
// IE <= 8 and other pre-ES6 engines fail this check
return false;
}
var a = [1, 2];
var result = a.splice();
if (a.length !== 2 || result.length !== 0) {
// Safari 5.0 has this bug
return false;
}
var obj = {};
Array.prototype.splice.call(obj, 0, 0, 1);
if (obj.length !== 1) {
return false;
}
var spliceWorksWithLargeSparseArrays = (function () {
// Per https://github.com/es-shims/es5-shim/issues/295
// Safari 7/8 breaks with sparse arrays of size 1e5 or greater
var arr = new Array(1e5);
// note: the index MUST be 8 or larger or the test will false pass
arr[8] = 'x';
arr.splice(1, 1);
for (var i = 0; i < arr.length; i += 1) {
if (arr[i] === 'x') {
return i === 7;
}
}
return false;
}());
var spliceWorksWithSmallSparseArrays = (function () {
// Per https://github.com/es-shims/es5-shim/issues/295
// Opera 12.15 breaks on this, no idea why.
var n = 256;
var arr = [];
arr[n] = 'a';
arr.splice(n + 1, 0, 'b');
return arr[n] === 'a';
}());
return spliceWorksWithLargeSparseArrays && spliceWorksWithSmallSparseArrays; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Array.prototype[Symbol.iterator]
?
function(){
return typeof Array.prototype[Symbol.iterator] === 'function'; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Array iterator prototype chain
?
function(){
// Iterator instance
var iterator = [][Symbol.iterator]();
// %ArrayIteratorPrototype%
var proto1 = Object.getPrototypeOf(iterator);
// %IteratorPrototype%
var proto2 = Object.getPrototypeOf(proto1);
return proto2.hasOwnProperty(Symbol.iterator) &&
!proto1 .hasOwnProperty(Symbol.iterator) &&
!iterator .hasOwnProperty(Symbol.iterator) &&
iterator[Symbol.iterator]() === iterator; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
No No |
Array.prototype[Symbol.unscopables]
?
function(){
var unscopables = Array.prototype[Symbol.unscopables];
if (!unscopables) {
return false;
}
var ns = "find,findIndex,fill,copyWithin,entries,keys,values".split(",");
for (var i = 0; i < ns.length; i++) {
if (Array.prototype[ns[i]] && !unscopables[ns[i]]) return false;
}
return true; }
|
Error Error |
Error Error |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Error No |
Yes Yes |
Number properties |
||||||||||
Number.isFinite
?
function(){
return typeof Number.isFinite === 'function'; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Number.isInteger
?
function(){
return typeof Number.isInteger === 'function'; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Number.isSafeInteger
?
function(){
return typeof Number.isSafeInteger === 'function'; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Number.isNaN
?
function(){
return typeof Number.isNaN === 'function'; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Number.parseFloat
?
function(){
var actualGlobal = Function('return this')();
return typeof Number.parseFloat === 'function'
&& Number.parseFloat === actualGlobal.parseFloat; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Number.parseInt
?
function(){
var actualGlobal = Function('return this')();
return typeof Number.parseInt === 'function'
&& Number.parseInt === actualGlobal.parseInt; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Number.EPSILON
?
function(){
return typeof Number.EPSILON === 'number'; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Number.MIN_SAFE_INTEGER
?
function(){
return typeof Number.MIN_SAFE_INTEGER === 'number'; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Number.MAX_SAFE_INTEGER
?
function(){
return typeof Number.MAX_SAFE_INTEGER === 'number'; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Math methods |
||||||||||
Math.clz32
?
function(){
return typeof Math.clz32 === "function"; }
|
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Math.imul
?
function(){
return typeof Math.imul === "function"; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Math.sign
?
function(){
return typeof Math.sign === "function"; }
|
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Math.log10
?
function(){
return typeof Math.log10 === "function"; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Math.log2
?
function(){
return typeof Math.log2 === "function"; }
|
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Math.log1p
?
function(){
return typeof Math.log1p === "function"; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Math.expm1
?
function(){
return typeof Math.expm1 === "function"; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Math.cosh
?
function(){
return typeof Math.cosh === "function"; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Math.sinh
?
function(){
return typeof Math.sinh === "function"; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Math.tanh
?
function(){
return typeof Math.tanh === "function"; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Math.acosh
?
function(){
return typeof Math.acosh === "function"; }
|
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Math.asinh
?
function(){
return typeof Math.asinh === "function"; }
|
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Math.atanh
?
function(){
return typeof Math.atanh === "function"; }
|
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Math.trunc
?
function(){
return typeof Math.trunc === "function"; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Math.fround
?
function(){
return typeof Math.fround === "function"; }
|
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Math.cbrt
?
function(){
return typeof Math.cbrt === "function"; }
|
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Math.hypot
?
function(){
return Math.hypot() === 0 &&
Math.hypot(1) === 1 &&
Math.hypot(9, 12, 20) === 25 &&
Math.hypot(27, 36, 60, 100) === 125; }
|
Error Error |
Error Error |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
|
||||||||||
Date.prototype[Symbol.toPrimitive]
?
function(){
var tp = Date.prototype[Symbol.toPrimitive];
return tp.call(Object(2), "number") === 2
&& tp.call(Object(2), "string") === "2"
&& tp.call(Object(2), "default") === "2"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Array is subclassable |
||||||||||
length property (accessing)
?
function(){
class C extends Array {}
var c = new C();
var len1 = c.length;
c[2] = 'foo';
var len2 = c.length;
return len1 === 0 && len2 === 3; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
length property (setting)
?
function(){
class C extends Array {}
var c = new C();
c[2] = 'foo';
c.length = 1;
return c.length === 1 && !(2 in c); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
correct prototype chain
?
function(){
class C extends Array {}
var c = new C();
return c instanceof C && c instanceof Array && Object.getPrototypeOf(C) === Array; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Array.isArray support
?
function(){
class C extends Array {}
return Array.isArray(new C()); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Array.prototype.concat
?
function(){
class C extends Array {}
var c = new C();
return c.concat(1) instanceof C; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Array.prototype.filter
?
function(){
class C extends Array {}
var c = new C();
return c.filter(Boolean) instanceof C; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Array.prototype.map
?
function(){
class C extends Array {}
var c = new C();
return c.map(Boolean) instanceof C; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Array.prototype.slice
?
function(){
class C extends Array {}
var c = new C();
c.push(2,4,6);
return c.slice(1,2) instanceof C; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Array.prototype.splice
?
function(){
class C extends Array {}
var c = new C();
c.push(2,4,6);
return c.splice(1,2) instanceof C; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Array.from
?
function(){
class C extends Array {}
return C.from({ length: 0 }) instanceof C; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Array.of
?
function(){
class C extends Array {}
return C.of(0) instanceof C; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
RegExp is subclassable |
||||||||||
basic functionality
?
function(){
class R extends RegExp {}
var r = new R("baz","g");
return r.global && r.source === "baz"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
correct prototype chain
?
function(){
class R extends RegExp {}
var r = new R("baz","g");
return r instanceof R && r instanceof RegExp && Object.getPrototypeOf(R) === RegExp; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
RegExp.prototype.exec
?
function(){
class R extends RegExp {}
var r = new R("baz","g");
return r.exec("foobarbaz")[0] === "baz" && r.lastIndex === 9; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
RegExp.prototype.test
?
function(){
class R extends RegExp {}
var r = new R("baz");
return r.test("foobarbaz"); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Function is subclassable |
||||||||||
can be called
?
function(){
class C extends Function {}
var c = new C("return 'foo';");
return c() === 'foo'; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
correct prototype chain
?
function(){
class C extends Function {}
var c = new C("return 'foo';");
return c instanceof C && c instanceof Function && Object.getPrototypeOf(C) === Function; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
can be used with "new"
?
function(){
class C extends Function {}
var c = new C("this.bar = 2;");
c.prototype.baz = 3;
return new c().bar === 2 && new c().baz === 3; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Function.prototype.call
?
function(){
class C extends Function {}
var c = new C("x", "return this.bar + x;");
return c.call({bar:1}, 2) === 3; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Function.prototype.apply
?
function(){
class C extends Function {}
var c = new C("x", "return this.bar + x;");
return c.apply({bar:1}, [2]) === 3; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Function.prototype.bind
?
function(){
class C extends Function {}
var c = new C("x", "y", "return this.bar + x + y;").bind({bar:1}, 2);
return c(6) === 9 && c instanceof C; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Promise is subclassable |
||||||||||
basic functionality
?
function(){
class P extends Promise {}
var p1 = new P(function(resolve, reject) { resolve("foo"); });
var p2 = new P(function(resolve, reject) { reject("quux"); });
var score = +(p1 instanceof P);
function thenFn(result) { score += (result === "foo"); check(); }
function catchFn(result) { score += (result === "quux"); check(); }
function shouldNotRun(result) { score = -Infinity; }
p1.then(thenFn, shouldNotRun);
p2.then(shouldNotRun, catchFn);
p1.catch(shouldNotRun);
p2.catch(catchFn);
p1.then(function() {
// P.prototype.then() should return a new P
score += p1.then() instanceof P && p1.then() !== p1;
check();
});
function check() {
if (score === 5) asyncTestPassed();
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
correct prototype chain
?
function(){
class C extends Promise {}
var c = new C(function(resolve, reject) { resolve("foo"); });
return c instanceof C && c instanceof Promise && Object.getPrototypeOf(C) === Promise; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Promise.all
?
function(){
class P extends Promise {}
var fulfills = P.all([
new Promise(function(resolve) { setTimeout(resolve,2000,"foo"); }),
new Promise(function(resolve) { setTimeout(resolve,1000,"bar"); })
]);
var rejects = P.all([
new Promise(function(_, reject) { setTimeout(reject, 2000,"baz"); }),
new Promise(function(_, reject) { setTimeout(reject, 1000,"qux"); })
]);
var score = +(fulfills instanceof P);
fulfills.then(function(result) { score += (result + "" === "foo,bar"); check(); });
rejects.catch(function(result) { score += (result === "qux"); check(); });
function check() {
if (score === 3) asyncTestPassed();
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Promise.race
?
function(){
class P extends Promise {}
var fulfills = P.race([
new Promise(function(resolve) { setTimeout(resolve,1000,"foo"); }),
new Promise(function(_, reject) { setTimeout(reject, 2000,"bar"); })
]);
var rejects = P.race([
new Promise(function(_, reject) { setTimeout(reject, 1000,"baz"); }),
new Promise(function(resolve) { setTimeout(resolve,2000,"qux"); })
]);
var score = +(fulfills instanceof P);
fulfills.then(function(result) { score += (result === "foo"); check(); });
rejects.catch(function(result) { score += (result === "baz"); check(); });
function check() {
if (score === 3) asyncTestPassed();
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
miscellaneous subclassables |
||||||||||
Boolean is subclassable
?
function(){
class C extends Boolean {}
var c = new C(true);
return c instanceof Boolean
&& c instanceof C
&& c == true; // eslint-disable-line eqeqeq }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Number is subclassable
?
function(){
class C extends Number {}
var c = new C(6);
return c instanceof Number
&& c instanceof C
&& +c === 6; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
String is subclassable
?
function(){
class C extends String {}
var c = new C("golly");
return c instanceof String
&& c instanceof C
&& c + '' === "golly"
&& c[0] === "g"
&& c.length === 5; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error is subclassable
?
function(){
class C extends Error {}
var c = new C();
return c instanceof Error
&& c instanceof C
&& Object.prototype.toString.call(c) === "[object Error]"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Map is subclassable
?
function(){
var key = {};
class M extends Map {}
var map = new M();
map.set(key, 123);
return map instanceof M && map.has(key) && map.get(key) === 123; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Set is subclassable
?
function(){
var obj = {};
class S extends Set {}
var set = new S();
set.add(123);
set.add(123);
return set instanceof S && set.has(123); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
prototype of bound functions |
||||||||||
basic functions
?
function(){
function correctProtoBound(proto) {
var f = function(){};
if (Object.setPrototypeOf) {
Object.setPrototypeOf(f, proto);
} else {
f.__proto__ = proto;
}
var boundF = Function.prototype.bind.call(f, null);
return Object.getPrototypeOf(boundF) === proto;
}
return correctProtoBound(Function.prototype)
&& correctProtoBound({})
&& correctProtoBound(null); }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
generator functions
?
function(){
function correctProtoBound(proto) {
var f = function*(){};
if (Object.setPrototypeOf) {
Object.setPrototypeOf(f, proto);
} else {
f.__proto__ = proto;
}
var boundF = Function.prototype.bind.call(f, null);
return Object.getPrototypeOf(boundF) === proto;
}
return correctProtoBound(Function.prototype)
&& correctProtoBound({})
&& correctProtoBound(null); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
No No |
No No |
No No |
arrow functions
?
function(){
function correctProtoBound(proto) {
var f = ()=>5;
if (Object.setPrototypeOf) {
Object.setPrototypeOf(f, proto);
} else {
f.__proto__ = proto;
}
var boundF = Function.prototype.bind.call(f, null);
return Object.getPrototypeOf(boundF) === proto;
}
return correctProtoBound(Function.prototype)
&& correctProtoBound({})
&& correctProtoBound(null); }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
classes
?
function(){
function correctProtoBound(proto) {
class C {}
if (Object.setPrototypeOf) {
Object.setPrototypeOf(C, proto);
} else {
C.__proto__ = proto;
}
var boundF = Function.prototype.bind.call(C, null);
return Object.getPrototypeOf(boundF) === proto;
}
return correctProtoBound(Function.prototype)
&& correctProtoBound({})
&& correctProtoBound(null); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
subclasses
?
function(){
function correctProtoBound(superclass) {
class C extends superclass {
constructor() {
return Object.create(null);
}
}
var boundF = Function.prototype.bind.call(C, null);
return Object.getPrototypeOf(boundF) === Object.getPrototypeOf(C);
}
return correctProtoBound(function(){})
&& correctProtoBound(Array)
&& correctProtoBound(null); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Proxy, internal 'get' calls |
||||||||||
ToPrimitive
?
function(){
// ToPrimitive -> Get -> [[Get]]
var get = [];
var p = new Proxy({toString:Function()}, { get: function(o, k) { get.push(k); return o[k]; }});
p + 3;
return get[0] === Symbol.toPrimitive && get.slice(1) + '' === "valueOf,toString"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
CreateListFromArrayLike
?
function(){
// CreateListFromArrayLike -> Get -> [[Get]]
var get = [];
var p = new Proxy({length:2, 0:0, 1:0}, { get: function(o, k) { get.push(k); return o[k]; }});
Function.prototype.apply({}, p);
return get + '' === "length,0,1"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
instanceof operator
?
function(){
// InstanceofOperator -> GetMethod -> GetV -> [[Get]]
// InstanceofOperator -> OrdinaryHasInstance -> Get -> [[Get]]
var get = [];
var p = new Proxy(Function(), { get: function(o, k) { get.push(k); return o[k]; }});
({}) instanceof p;
return get[0] === Symbol.hasInstance && get.slice(1) + '' === "prototype"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
HasBinding
?
function(){
// HasBinding -> Get -> [[Get]]
var get = [];
var p = new Proxy({foo:1}, { get: function(o, k) { get.push(k); return o[k]; }});
p[Symbol.unscopables] = p;
with(p) {
typeof foo;
}
return get[0] === Symbol.unscopables && get.slice(1) + '' === "foo"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
CreateDynamicFunction
?
function(){
// CreateDynamicFunction -> GetPrototypeFromConstructor -> Get -> [[Get]]
var get = [];
var p = new Proxy(Function, { get: function(o, k) { get.push(k); return o[k]; }});
new p;
return get + '' === "prototype"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
ClassDefinitionEvaluation
?
function(){
// ClassDefinitionEvaluation -> Get -> [[Get]]
var get = [];
var p = new Proxy(Function(), { get: function(o, k) { get.push(k); return o[k]; }});
class C extends p {}
return get + '' === "prototype"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
IteratorComplete, IteratorValue
?
function(){
// IteratorComplete -> Get -> [[Get]]
// IteratorValue -> Get -> [[Get]]
var get = [];
var iterable = {};
iterable[Symbol.iterator] = function() {
return {
next: function() {
return new Proxy({ value: 2, done: false }, { get: function(o, k) { get.push(k); return o[k]; }});
}
};
}
var i = 0;
for(var e of iterable) {
if (++i >= 2) break;
}
return get + '' === "done,value,done,value"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
ToPropertyDescriptor
?
function(){
// ToPropertyDescriptor -> Get -> [[Get]]
var get = [];
var p = new Proxy({
enumerable: true, configurable: true, value: true,
writable: true, get: Function(), set: Function()
}, { get: function(o, k) { get.push(k); return o[k]; }});
try {
// This will throw, since it will have true for both "get" and "value",
// but not before performing a Get on every property.
Object.defineProperty({}, "foo", p);
} catch(e) {
return get + '' === "enumerable,configurable,value,writable,get,set";
} }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Object.assign
?
function(){
// Object.assign -> Get -> [[Get]]
var get = [];
var p = new Proxy({foo:1, bar:2}, { get: function(o, k) { get.push(k); return o[k]; }});
Object.assign({}, p);
return get + '' === "foo,bar"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Object.defineProperties
?
function(){
// Object.defineProperties -> Get -> [[Get]]
var get = [];
var p = new Proxy({foo:{}, bar:{}}, { get: function(o, k) { get.push(k); return o[k]; }});
Object.defineProperties({}, p);
return get + '' === "foo,bar"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Function.prototype.bind
?
function(){
// Function.prototype.bind -> Get -> [[Get]]
var get = [];
var p = new Proxy(Function(), { get: function(o, k) { get.push(k); return o[k]; }});
Function.prototype.bind.call(p);
return get + '' === "length,name"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Error.prototype.toString
?
function(){
// Error.prototype.toString -> Get -> [[Get]]
var get = [];
var p = new Proxy({}, { get: function(o, k) { get.push(k); return o[k]; }});
Error.prototype.toString.call(p);
return get + '' === "name,message"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
String.raw
?
function(){
// String.raw -> Get -> [[Get]]
var get = [];
var raw = new Proxy({length: 2, 0: '', 1: ''}, { get: function(o, k) { get.push(k); return o[k]; }});
var p = new Proxy({raw: raw}, { get: function(o, k) { get.push(k); return o[k]; }});
String.raw(p);
return get + '' === "raw,length,0,1"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
RegExp constructor
?
function(){
// RegExp -> Get -> [[Get]]
var get = [];
var re = { constructor: null };
re[Symbol.match] = true;
var p = new Proxy(re, { get: function(o, k) { get.push(k); return o[k]; }});
RegExp(p);
return get[0] === Symbol.match && get.slice(1) + '' === "constructor,source,flags"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
RegExp.prototype.flags
?
function(){
// RegExp.prototype.flags -> Get -> [[Get]]
var expected = [];
// Sorted alphabetically by shortname – "gimsuy".
if ('hasIndices' in RegExp.prototype) expected.push('hasIndices');
if ('global' in RegExp.prototype) expected.push('global');
if ('ignoreCase' in RegExp.prototype) expected.push('ignoreCase');
if ('multiline' in RegExp.prototype) expected.push('multiline');
if ('dotAll' in RegExp.prototype) expected.push('dotAll');
if ('unicode' in RegExp.prototype) expected.push('unicode');
if ('unicodeSets' in RegExp.prototype) expected.push('unicodeSets');
if ('sticky' in RegExp.prototype) expected.push('sticky');
var actual = [];
var p = new Proxy({}, { get: function(o, k) { actual.push(k); return o[k]; }});
Object.getOwnPropertyDescriptor(RegExp.prototype, 'flags').get.call(p);
if (expected.length !== actual.length) return false;
for (var i = 0; i < expected.length; i++) {
if (expected[i] !== actual[i]) return false;
}
return true; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
RegExp.prototype.test
?
function(){
// RegExp.prototype.test -> RegExpExec -> Get -> [[Get]]
var get = [];
var p = new Proxy({ exec: function() { return null; } }, { get: function(o, k) { get.push(k); return o[k]; }});
RegExp.prototype.test.call(p);
return get + '' === "exec"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
RegExp.prototype.toString
?
function(){
// RegExp.prototype.toString -> Get -> [[Get]]
var get = [];
var p = new Proxy({}, { get: function(o, k) { get.push(k); return o[k]; }});
RegExp.prototype.toString.call(p);
return get + '' === "source,flags"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
RegExp.prototype[Symbol.match]
?
function(){
// RegExp.prototype[Symbol.match] -> Get -> [[Get]]
var get = [];
var p = new Proxy({ exec: function() { return null; } }, { get: function(o, k) { get.push(k); return o[k]; }});
RegExp.prototype[Symbol.match].call(p);
p.global = true;
RegExp.prototype[Symbol.match].call(p);
var str = get + '';
return str === "global,exec,global,unicode,exec" || str === 'flags,exec,flags,exec'; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
RegExp.prototype[Symbol.replace]
?
function(){
// RegExp.prototype[Symbol.replace] -> Get -> [[Get]]
var get = [];
var p = new Proxy({ exec: function() { return null; } }, { get: function(o, k) { get.push(k); return o[k]; }});
RegExp.prototype[Symbol.replace].call(p);
p.global = true;
RegExp.prototype[Symbol.replace].call(p);
var str = get + '';
return str === "global,exec,global,unicode,exec" || str === 'flags,exec,flags,exec'; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
RegExp.prototype[Symbol.search]
?
function(){
// RegExp.prototype[Symbol.search] -> Get -> [[Get]]
var get = [];
var p = new Proxy({ exec: function() { return null; } }, { get: function(o, k) { get.push(k); return o[k]; }});
RegExp.prototype[Symbol.search].call(p);
return get + '' === "lastIndex,exec,lastIndex"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
RegExp.prototype[Symbol.split]
?
function(){
// RegExp.prototype[Symbol.split] -> Get -> [[Get]]
var get = [];
var constructor = Function();
constructor[Symbol.species] = Object;
var p = new Proxy({ constructor: constructor, flags: '', exec: function() { return null; } }, { get: function(o, k) { get.push(k); return o[k]; }});
RegExp.prototype[Symbol.split].call(p, "");
return get + '' === "constructor,flags,exec"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Array.from
?
function(){
// Array.from -> Get -> [[Get]]
var get = [];
var p = new Proxy({length: 2, 0: '', 1: ''}, { get: function(o, k) { get.push(k); return o[k]; }});
Array.from(p);
return get[0] === Symbol.iterator && get.slice(1) + '' === "length,0,1"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Array.prototype.concat
?
function(){
// Array.prototype.concat -> Get -> [[Get]]
var get = [];
var arr = [1];
arr.constructor = void undefined;
var p = new Proxy(arr, { get: function(o, k) { get.push(k); return o[k]; }});
Array.prototype.concat.call(p,p);
return get[0] === "constructor"
&& get[1] === Symbol.isConcatSpreadable
&& get[2] === "length"
&& get[3] === "0"
&& get[4] === get[1] && get[5] === get[2] && get[6] === get[3]
&& get.length === 7; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Array.prototype iteration methods
?
function(){
// Array.prototype methods -> Get -> [[Get]]
var methods = ['copyWithin', 'every', 'fill', 'filter', 'find', 'findIndex', 'forEach',
'indexOf', 'join', 'lastIndexOf', 'map', 'reduce', 'reduceRight', 'some'];
var get;
var p = new Proxy({length: 2, 0: '', 1: ''}, { get: function(o, k) { get.push(k); return o[k]; }});
for(var i = 0; i < methods.length; i+=1) {
get = [];
Array.prototype[methods[i]].call(p, Function());
if (get + '' !== (
methods[i] === 'fill' ? "length" :
methods[i] === 'every' ? "length,0" :
methods[i] === 'lastIndexOf' || methods[i] === 'reduceRight' ? "length,1,0" :
"length,0,1"
)) {
return false;
}
}
return true; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Array.prototype.pop
?
function(){
// Array.prototype.pop -> Get -> [[Get]]
var get = [];
var p = new Proxy([0,1,2,3], { get: function(o, k) { get.push(k); return o[k]; }});
Array.prototype.pop.call(p);
return get + '' === "length,3"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Array.prototype.reverse
?
function(){
// Array.prototype.reverse -> Get -> [[Get]]
var get = [];
var p = new Proxy([0,,2,,4,,], { get: function(o, k) { get.push(k); return o[k]; }});
Array.prototype.reverse.call(p);
return get + '' === "length,0,4,2"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Array.prototype.shift
?
function(){
// Array.prototype.shift -> Get -> [[Get]]
var get = [];
var p = new Proxy([0,1,2,3], { get: function(o, k) { get.push(k); return o[k]; }});
Array.prototype.shift.call(p);
return get + '' === "length,0,1,2,3"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Array.prototype.splice
?
function(){
// Array.prototype.splice -> Get -> [[Get]]
var get = [];
var p = new Proxy([0,1,2,3], { get: function(o, k) { get.push(k); return o[k]; }});
Array.prototype.splice.call(p,1,1);
Array.prototype.splice.call(p,1,0,1);
return get + '' === "length,constructor,1,2,3,length,constructor,2,1"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Array.prototype.toString
?
function(){
// Array.prototype.toString -> Get -> [[Get]]
var get = [];
var p = new Proxy({ join:Function() }, { get: function(o, k) { get.push(k); return o[k]; }});
Array.prototype.toString.call(p);
return get + '' === "join"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
JSON.stringify
?
function(){
// JSON.stringify -> Get -> [[Get]]
var get = [];
var p = new Proxy({}, { get: function(o, k) { get.push(k); return o[k]; }});
JSON.stringify(p);
return get + '' === "toJSON"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Promise resolve functions
?
function(){
// Promise resolve functions -> Get -> [[Get]]
var get = [];
var p = new Proxy({}, { get: function(o, k) { get.push(k); return o[k]; }});
new Promise(function(resolve){ resolve(p); });
return get + '' === "then"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
String.prototype.match
?
function(){
// String.prototype.match -> Get -> [[Get]]
var get = [];
var proxied = {};
proxied[Symbol.toPrimitive] = Function();
var p = new Proxy(proxied, { get: function(o, k) { get.push(k); return o[k]; }});
"".match(p);
return get[0] === Symbol.match && get[1] === Symbol.toPrimitive && get.length === 2; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
String.prototype.replace
?
function(){
// String.prototype.replace functions -> Get -> [[Get]]
var get = [];
var proxied = {};
proxied[Symbol.toPrimitive] = Function();
var p = new Proxy(proxied, { get: function(o, k) { get.push(k); return o[k]; }});
"".replace(p);
return get[0] === Symbol.replace && get[1] === Symbol.toPrimitive && get.length === 2; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
String.prototype.search
?
function(){
// String.prototype.search functions -> Get -> [[Get]]
var get = [];
var proxied = {};
proxied[Symbol.toPrimitive] = Function();
var p = new Proxy(proxied, { get: function(o, k) { get.push(k); return o[k]; }});
"".search(p);
return get[0] === Symbol.search && get[1] === Symbol.toPrimitive && get.length === 2; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
String.prototype.split
?
function(){
// String.prototype.split functions -> Get -> [[Get]]
var get = [];
var proxied = {};
proxied[Symbol.toPrimitive] = Function();
var p = new Proxy(proxied, { get: function(o, k) { get.push(k); return o[k]; }});
"".split(p);
return get[0] === Symbol.split && get[1] === Symbol.toPrimitive && get.length === 2; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Date.prototype.toJSON
?
function(){
// Date.prototype.toJSON -> ToPrimitive -> Get -> [[Get]]
// Date.prototype.toJSON -> Invoke -> GetMethod -> GetV -> [[Get]]
var get = [];
var p = new Proxy({toString:Function(),toISOString:Function()}, { get: function(o, k) { get.push(k); return o[k]; }});
Date.prototype.toJSON.call(p);
return get[0] === Symbol.toPrimitive && get.slice(1) + '' === "valueOf,toString,toISOString"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Proxy, internal 'set' calls |
||||||||||
Object.assign
?
function(){
// Object.assign -> Set -> [[Set]]
var set = [];
var p = new Proxy({}, { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
Object.assign(p, { foo: 1, bar: 2 });
return set + '' === "foo,bar"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Array.from
?
function(){
// Array.from -> Set -> [[Set]]
var set = [];
var p = new Proxy({}, { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
Array.from.call(function(){ return p; }, {length:2, 0:1, 1:2});
return set + '' === "length"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Array.of
?
function(){
// Array.from -> Set -> [[Set]]
var set = [];
var p = new Proxy({}, { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
Array.of.call(function(){ return p; }, 1, 2, 3);
return set + '' === "length"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Array.prototype.copyWithin
?
function(){
// Array.prototype.copyWithin -> Set -> [[Set]]
var set = [];
var p = new Proxy([1,2,3,4,5,6], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
p.copyWithin(0, 3);
return set + '' === "0,1,2"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Array.prototype.fill
?
function(){
// Array.prototype.fill -> Set -> [[Set]]
var set = [];
var p = new Proxy([1,2,3,4,5,6], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
p.fill(0, 3);
return set + '' === "3,4,5"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Array.prototype.pop
?
function(){
// Array.prototype.pop -> Set -> [[Set]]
var set = [];
var p = new Proxy([], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
p.pop();
return set + '' === "length"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Array.prototype.push
?
function(){
// Array.prototype.push -> Set -> [[Set]]
var set = [];
var p = new Proxy([], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
p.push(0,0,0);
return set + '' === "0,1,2,length"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Array.prototype.reverse
?
function(){
// Array.prototype.reverse -> Set -> [[Set]]
var set = [];
var p = new Proxy([0,0,0,,], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
p.reverse();
return set + '' === "3,1,2"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Array.prototype.shift
?
function(){
// Array.prototype.shift -> Set -> [[Set]]
var set = [];
var p = new Proxy([0,0,,0], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
p.shift();
return set + '' === "0,2,length"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Array.prototype.splice
?
function(){
// Array.prototype.splice -> Set -> [[Set]]
var set = [];
var p = new Proxy([1,2,3], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
p.splice(1,0,0);
return set + '' === "3,2,1,length"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Array.prototype.unshift
?
function(){
// Array.prototype.unshift -> Set -> [[Set]]
var set = [];
var p = new Proxy([0,0,,0], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
p.unshift(0,1);
return set + '' === "5,3,2,0,1,length"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Proxy, internal 'defineProperty' calls |
||||||||||
[[Set]]
?
function(){
// [[Set]] -> [[DefineOwnProperty]]
var def = [];
var p = new Proxy({foo:1, bar:2}, { defineProperty: function(o, v, desc) { def.push(v); Object.defineProperty(o, v, desc); return true; }});
p.foo = 2; p.bar = 4;
return def + '' === "foo,bar"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
SetIntegrityLevel
?
function(){
// SetIntegrityLevel -> DefinePropertyOrThrow -> [[DefineOwnProperty]]
var def = [];
var p = new Proxy({foo:1, bar:2}, { defineProperty: function(o, v, desc) { def.push(v); Object.defineProperty(o, v, desc); return true; }});
Object.freeze(p);
return def + '' === "foo,bar"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Proxy, internal 'deleteProperty' calls |
||||||||||
Array.prototype.copyWithin
?
function(){
// Array.prototype.copyWithin -> DeletePropertyOrThrow -> [[Delete]]
var del = [];
var p = new Proxy([0,0,0,,,,], { deleteProperty: function(o, v) { del.push(v); return delete o[v]; }});
p.copyWithin(0,3);
return del + '' === "0,1,2"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Array.prototype.pop
?
function(){
// Array.prototype.pop -> DeletePropertyOrThrow -> [[Delete]]
var del = [];
var p = new Proxy([0,0,0], { deleteProperty: function(o, v) { del.push(v); return delete o[v]; }});
p.pop();
return del + '' === "2"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Array.prototype.reverse
?
function(){
// Array.prototype.reverse -> DeletePropertyOrThrow -> [[Delete]]
var del = [];
var p = new Proxy([0,,2,,4,,], { deleteProperty: function(o, v) { del.push(v); return delete o[v]; }});
p.reverse();
return del + '' === "0,4,2"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Array.prototype.shift
?
function(){
// Array.prototype.shift -> DeletePropertyOrThrow -> [[Delete]]
var del = [];
var p = new Proxy([0,,0,,0,0], { deleteProperty: function(o, v) { del.push(v); return delete o[v]; }});
p.shift();
return del + '' === "0,2,5"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Array.prototype.splice
?
function(){
// Array.prototype.splice -> DeletePropertyOrThrow -> [[Delete]]
var del = [];
var p = new Proxy([0,0,0,0,,0], { deleteProperty: function(o, v) { del.push(v); return delete o[v]; }});
p.splice(2,2,0);
return del + '' === "3,5"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Array.prototype.unshift
?
function(){
// Array.prototype.unshift -> DeletePropertyOrThrow -> [[Delete]]
var del = [];
var p = new Proxy([0,0,,0,,0], { deleteProperty: function(o, v) { del.push(v); return delete o[v]; }});
p.unshift(0);
return del + '' === "5,3"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Proxy, internal 'getOwnPropertyDescriptor' calls |
||||||||||
[[Set]]
?
function(){
// [[Set]] -> [[GetOwnProperty]]
var gopd = [];
var p = new Proxy({},
{ getOwnPropertyDescriptor: function(o, v) { gopd.push(v); return Object.getOwnPropertyDescriptor(o, v); }});
p.foo = 1; p.bar = 1;
return gopd + '' === "foo,bar"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Object.assign
?
function(){
// Object.assign -> [[GetOwnProperty]]
var gopd = [];
var p = new Proxy({foo:1, bar:2},
{ getOwnPropertyDescriptor: function(o, v) { gopd.push(v); return Object.getOwnPropertyDescriptor(o, v); }});
Object.assign({}, p);
return gopd + '' === "foo,bar"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Object.prototype.hasOwnProperty
?
function(){
// Object.prototype.hasOwnProperty -> HasOwnProperty -> [[GetOwnProperty]]
var gopd = [];
var p = new Proxy({foo:1, bar:2},
{ getOwnPropertyDescriptor: function(o, v) { gopd.push(v); return Object.getOwnPropertyDescriptor(o, v); }});
p.hasOwnProperty('garply');
return gopd + '' === "garply"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Function.prototype.bind
?
function(){
// Function.prototype.bind -> HasOwnProperty -> [[GetOwnProperty]]
var gopd = [];
var p = new Proxy(Function(),
{ getOwnPropertyDescriptor: function(o, v) { gopd.push(v); return Object.getOwnPropertyDescriptor(o, v); }});
p.bind();
return gopd + '' === "length"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Proxy, internal 'ownKeys' calls |
||||||||||
SetIntegrityLevel
?
function(){
// SetIntegrityLevel -> [[OwnPropertyKeys]]
var ownKeysCalled = 0;
var p = new Proxy({}, { ownKeys: function(o) { ownKeysCalled++; return Object.keys(o); }});
Object.freeze(p);
return ownKeysCalled === 1; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
TestIntegrityLevel
?
function(){
// TestIntegrityLevel -> [[OwnPropertyKeys]]
var ownKeysCalled = 0;
var p = new Proxy(Object.preventExtensions({}), { ownKeys: function(o) { ownKeysCalled++; return Object.keys(o); }});
Object.isFrozen(p);
return ownKeysCalled === 1; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
SerializeJSONObject
?
function(){
// SerializeJSONObject -> EnumerableOwnNames -> [[OwnPropertyKeys]]
var ownKeysCalled = 0;
var p = new Proxy({}, { ownKeys: function(o) { ownKeysCalled++; return Object.keys(o); }});
JSON.stringify({a:p,b:p});
return ownKeysCalled === 2; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
Object static methods accept primitives |
||||||||||
Object.getPrototypeOf
?
function(){
return Object.getPrototypeOf('a').constructor === String; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Object.getOwnPropertyDescriptor
?
function(){
return Object.getOwnPropertyDescriptor('a', 'foo') === void undefined; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Object.getOwnPropertyNames
?
function(){
var s = Object.getOwnPropertyNames('a');
return s.length === 2 &&
((s[0] === 'length' && s[1] === '0') || (s[0] === '0' && s[1] === 'length')); }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Object.seal
?
function(){
return Object.seal('a') === 'a'; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Object.freeze
?
function(){
return Object.freeze('a') === 'a'; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Object.preventExtensions
?
function(){
return Object.preventExtensions('a') === 'a'; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Object.isSealed
?
function(){
return Object.isSealed('a') === true; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Object.isFrozen
?
function(){
return Object.isFrozen('a') === true; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Object.isExtensible
?
function(){
return Object.isExtensible('a') === false; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
Object.keys
?
function(){
var s = Object.keys('a');
return s.length === 1 && s[0] === '0'; }
|
Error Error |
Error Error |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Error Flag |
Yes Yes |
own property order |
||||||||||
Object.keys
?
function(){
var obj = {
// Non-negative integer names appear first in value order
2: true,
0: true,
1: true,
// Other string names appear in source order
' ': true,
// Non-negative integers are sorted above other names
9: true,
D: true,
B: true,
// Negative integers are treated as other names
'-1': true
};
// Other string names are added in order of creation
obj.A = true;
// Non-negative integer names, conversely, ignore order of creation
obj[3] = true;
// Having a total of 20+ properties doesn't affect property order
"EFGHIJKLMNOPQRSTUVWXYZ".split('').forEach(function(key){
obj[key] = true;
});
// Object.defineProperty doesn't affect the above rules
Object.defineProperty(obj, 'C', { value: true, enumerable: true });
Object.defineProperty(obj, '4', { value: true, enumerable: true });
// Deleting and reinserting a property doesn't preserve its position
delete obj[2];
obj[2] = true;
var forInOrder = '';
for(var key in obj)forInOrder += key;
return Object.keys(obj).join('') === forInOrder; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Object.getOwnPropertyNames
?
function(){
var obj = {
2: true,
0: true,
1: true,
' ': true,
9: true,
D: true,
B: true,
'-1': true
};
obj.A = true;
obj[3] = true;
"EFGHIJKLMNOPQRSTUVWXYZ".split('').forEach(function(key){
obj[key] = true;
});
Object.defineProperty(obj, 'C', { value: true, enumerable: true });
Object.defineProperty(obj, '4', { value: true, enumerable: true });
delete obj[2];
obj[2] = true;
return Object.getOwnPropertyNames(obj).join('') === "012349 DB-1AEFGHIJKLMNOPQRSTUVWXYZC"; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No Flag |
Yes Yes |
Object.assign
?
function(){
var result = '';
var target = {};
"012349 DBACEFGHIJKLMNOPQRST".split('').concat(-1).forEach(function(key){
Object.defineProperty(target, key, {
set: function(){
result += key;
}
})
});
var obj = {2: 2, 0: 0, 1: 1, ' ': ' ', 9: 9, D: 'D', B: 'B', '-1': '-1'};
Object.defineProperty(obj, 'A', {value: 'A', enumerable: true});
Object.defineProperty(obj, '3', {value: '3', enumerable: true});
Object.defineProperty(obj, 'C', {value: 'C', enumerable: true});
Object.defineProperty(obj, '4', {value: '4', enumerable: true});
delete obj[2];
obj[2] = true;
"EFGHIJKLMNOPQRST".split('').forEach(function(key){
obj[key] = key;
});
Object.assign(target, obj);
return result === "012349 DB-1ACEFGHIJKLMNOPQRST"; }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No No |
No No |
No Flag |
Yes Yes |
JSON.stringify
?
function(){
var obj = {
2: true,
0: true,
1: true,
' ': true,
9: true,
D: true,
B: true,
'-1': true
};
obj.A = true;
obj[3] = true;
"EFGHIJKLMNOPQRSTUVWXYZ".split('').forEach(function(key){
obj[key] = true;
});
Object.defineProperty(obj, 'C', { value: true, enumerable: true });
Object.defineProperty(obj, '4', { value: true, enumerable: true });
delete obj[2];
obj[2] = true;
return JSON.stringify(obj) ===
'{"0":true,"1":true,"2":true,"3":true,"4":true,"9":true," ":true,"D":true,"B":true,"-1":true,"A":true,"E":true,"F":true,"G":true,"H":true,"I":true,"J":true,"K":true,"L":true,"M":true,"N":true,"O":true,"P":true,"Q":true,"R":true,"S":true,"T":true,"U":true,"V":true,"W":true,"X":true,"Y":true,"Z":true,"C":true}'; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No Flag |
Yes Yes |
JSON.parse
?
function(){
var result = '';
JSON.parse(
'{"0":true,"1":true,"2":true,"3":true,"4":true,"9":true," ":true,"D":true,"B":true,"-1":true,"E":true,"F":true,"G":true,"H":true,"I":true,"J":true,"K":true,"L":true,"A":true,"C":true}',
function reviver(k,v) {
result += k;
return v;
}
);
return result === "012349 DB-1EFGHIJKLAC"; }
|
Yes Yes |
Yes Yes |
Yes No |
Yes No |
Yes No |
Yes No |
Yes No |
Yes No |
Yes Yes |
Yes Yes |
Reflect.ownKeys, string key order
?
function(){
var obj = {
2: true,
0: true,
1: true,
' ': true,
9: true,
D: true,
B: true,
'-1': true
};
obj.A = true;
obj[3] = true;
"EFGHIJKLMNOPQRSTUVWXYZ".split('').forEach(function(key){
obj[key] = true;
});
Object.defineProperty(obj, 'C', { value: true, enumerable: true });
Object.defineProperty(obj, '4', { value: true, enumerable: true });
delete obj[2];
obj[2] = true;
return Reflect.ownKeys(obj).join('') === "012349 DB-1AEFGHIJKLMNOPQRSTUVWXYZC"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Reflect.ownKeys, symbol key order
?
function(){
var sym1 = Symbol(), sym2 = Symbol(), sym3 = Symbol();
var obj = {
1: true,
A: true
};
obj.B = true;
obj[sym1] = true;
obj[2] = true;
obj[sym2] = true;
Object.defineProperty(obj, 'C', { value: true, enumerable: true });
Object.defineProperty(obj, sym3,{ value: true, enumerable: true });
Object.defineProperty(obj, 'D', { value: true, enumerable: true });
var result = Reflect.ownKeys(obj);
var l = result.length;
return result[l-3] === sym1 && result[l-2] === sym2 && result[l-1] === sym3; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Updated identifier syntax |
||||||||||
var ⸯ;
?
function(){
try {
eval('var ⸯ');
} catch(e) {
return true;
} }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
var 𐋀;
?
function(){
var 𐋀;
return true; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Yes Yes |
no escaped reserved words as identifiers
?
function(){
var \u0061;
try {
eval('var v\\u0061r');
} catch(e) {
return true;
} }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No Flag |
Yes Yes |
miscellaneous |
||||||||||
duplicate property names in strict mode
?
function(){
'use strict';
return this === void undefined && ({ a:1, a:1 }).a === 1; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
no semicolon needed after do-while
?
function(){
do {} while (false) return true; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
no assignments allowed in for-in head in strict mode
?
function(){
'use strict';
try {
eval('for (var i = 0 in {}) {}');
}
catch(e) {
return true;
} }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
accessors aren't constructors
?
function(){
var f = (Object.getOwnPropertyDescriptor({get a(){}}, 'a')).get;
try {
new f;
} catch(e) {
return true;
} }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Invalid Date
?
function(){
return new Date(NaN) + "" === "Invalid Date"; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
RegExp constructor can alter flags
?
function(){
return new RegExp(/./im, "g").global === true; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
RegExp.prototype.toString generic and uses "flags" property
?
function(){
return RegExp.prototype.toString.call({source: 'foo', flags: 'bar'}) === '/foo/bar'; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Yes Yes |
Yes Yes |
built-in prototypes are not instances
?
function(){
try {
RegExp.prototype.exec(); return false;
} catch(e) {}
try {
Date.prototype.valueOf(); return false;
} catch(e) {}
if (![Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError].every(function (E) {
return Object.prototype.toString.call(E.prototype) === '[object Object]';
})) {
return false;
}
return true; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
function 'length' is configurable
?
function(){
var fn = function(a, b) {};
var desc = Object.getOwnPropertyDescriptor(fn, "length");
if (desc.configurable) {
Object.defineProperty(fn, "length", { value: 1 });
return fn.length === 1;
}
return false; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
non-strict function semantics |
||||||||||
hoisted block-level function declaration
?
function(){
// Note: only available outside of strict mode.
if (!this) return false;
var passed = f() === 1;
function f() { return 1; }
passed &= typeof g === 'undefined';
{ function g() { return 1; } }
passed &= g() === 1;
passed &= h() === 2;
{ function h() { return 1; } }
function h() { return 2; }
passed &= h() === 1;
return passed; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
labeled function statements
?
function(){
// Note: only available outside of strict mode.
if (!this) return false;
label: function foo() { return 2; }
return foo() === 2; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
function statements in if-statement clauses
?
function(){
// Note: only available outside of strict mode.
if (!this) return false;
if(true) function foo() { return 2; }
if(false) {} else function bar() { return 3; }
if(true) function baz() { return 4; } else {}
if(false) function qux() { return 5; } else function qux() { return 6; }
return foo() === 2 && bar() === 3 && baz() === 4 && qux() === 6; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
__proto__ in object literals |
||||||||||
basic support
?
function(){
return { __proto__ : [] } instanceof Array
&& !({ __proto__ : null } instanceof Object); }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
multiple __proto__ is an error
?
function(){
try {
eval("({ __proto__ : [], __proto__: {} })");
}
catch(e) {
return true;
} }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
not a computed property
?
function(){
if (!({ __proto__ : [] } instanceof Array)) {
return false;
}
var a = "__proto__";
return !({ [a] : [] } instanceof Array); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
No No |
not a shorthand property
?
function(){
if (!({ __proto__ : [] } instanceof Array)) {
return false;
}
var __proto__ = [];
return !({ __proto__ } instanceof Array); }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error No |
Error No |
No No |
not a shorthand method
?
function(){
if (!({ __proto__ : [] } instanceof Array)) {
return false;
}
return !({ __proto__(){} } instanceof Function); }
|
Error Error |
Error Error |
No No |
No No |
No No |
No No |
No Flag |
No Flag |
No Flag |
Yes Yes |
Object.prototype.__proto__ |
||||||||||
get prototype
?
function(){
var A = function(){};
return (new A()).__proto__ === A.prototype; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
set prototype
?
function(){
var o = {};
o.__proto__ = Array.prototype;
return o instanceof Array; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
absent from Object.create(null)
?
function(){
var o = Object.create(null), p = {};
o.__proto__ = p;
return Object.getPrototypeOf(o) !== p; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
present in hasOwnProperty()
?
function(){
return Object.prototype.hasOwnProperty('__proto__'); }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
correct property descriptor
?
function(){
var desc = Object.getOwnPropertyDescriptor(Object.prototype,"__proto__");
var A = function(){};
return (desc
&& "get" in desc
&& "set" in desc
&& desc.configurable
&& !desc.enumerable); }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
present in Object.getOwnPropertyNames()
?
function(){
return Object.getOwnPropertyNames(Object.prototype).indexOf('__proto__') > -1; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
No No |
String.prototype HTML methods |
||||||||||
existence
?
function(){
var i, names = ["anchor", "big", "bold", "fixed", "fontcolor", "fontsize",
"italics", "link", "small", "strike", "sub", "sup"];
for (i = 0; i < names.length; i++) {
if (typeof String.prototype[names[i]] !== 'function') {
return false;
}
}
return true; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
tags' names are lowercase
?
function(){
var i, names = ["anchor", "big", "bold", "fixed", "fontcolor", "fontsize",
"italics", "link", "small", "strike", "sub", "sup"];
for (i = 0; i < names.length; i++) {
if (""[names[i]]().toLowerCase() !== ""[names[i]]()) {
return false;
}
}
return true; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
quotes in arguments are escaped
?
function(){
var i, names = ["anchor", "fontcolor", "fontsize", "link"];
for (i = 0; i < names.length; i++) {
if (""[names[i]]('"') !== ""[names[i]]('&' + 'quot;')) {
return false;
}
}
return true; }
|
No No |
No No |
No No |
No No |
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
RegExp.prototype.compile |
||||||||||
basic functionality
?
function(){
if (typeof RegExp.prototype.compile !== 'function')
return false
var rx = /a/;
rx.compile('b');
return rx.test('b'); }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
returns this
?
function(){
var rx = /a/;
return rx.compile('b') === rx; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
RegExp syntax extensions |
||||||||||
hyphens in character sets
?
function(){
return /[\w-_]/.exec("-")[0] === "-"; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
invalid character escapes
?
function(){
return /\z/.exec("\\z")[0] === "z"
&& /[\z]/.exec("[\\z]")[0] === "z"; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
invalid control-character escapes
?
function(){
return /\c2/.exec("\\c2")[0] === "\\c2"; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
invalid Unicode escapes
?
function(){
return /\u1/.exec("u1")[0] === "u1"
&& /[\u1]/.exec("u")[0] === "u"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
invalid hexadecimal escapes
?
function(){
return /\x1/.exec("x1")[0] === "x1"
&& /[\x1]/.exec("x")[0] === "x"; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
incomplete patterns and quantifiers
?
function(){
return /x{1/.exec("x{1")[0] === "x{1"
&& /x]1/.exec("x]1")[0] === "x]1"; }
|
No No |
No No |
No No |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
octal escape sequences
?
function(){
return /\041/.exec("!")[0] === "!"
&& /[\041]/.exec("!")[0] === "!"; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
invalid backreferences become octal escapes
?
function(){
return /\41/.exec("!")[0] === "!"
&& /[\41]/.exec("!")[0] === "!"; }
|
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
Yes Yes |
|
||||||||||
HTML-style comments
?
function(){
--> A comment
<!-- Another comment
var a = 3; <!-- Another comment
return a === 3; }
|
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |
Error Error |