Last active
September 25, 2016 06:59
-
-
Save MutableLoss/301d99a439ebe6c1635e00217812f06c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Proper Tail Calls | |
// direct recursion | |
function() { | |
'use strict'; | |
return (function f(n) { | |
if (n <= 0) { | |
return 'foo'; | |
} | |
return f(n - 1); | |
}(1e6)) === 'foo'; | |
} | |
// 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"; | |
} | |
// default function parameters | |
// basic functionality | |
function(){ | |
return (function (a = 1, b = 2) { return a === 3 && b === 2; }(3)); | |
} | |
// explicit undefined defers to the default | |
function(){ | |
return (function (a = 1, b = 2) { return a === 1 && b === 3; }(undefined, 3)); | |
} | |
// defaults can refer to previous params | |
function(){ | |
return (function (a, b = a) { return b === 5; }(5)); | |
} | |
// 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")); | |
} | |
// 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; | |
}()); | |
} | |
// separate scope | |
function(){ | |
return (function(a=function(){ | |
return typeof b === 'undefined'; | |
}){ | |
var b = 1; | |
return a(); | |
}()); | |
} | |
// new Function() support | |
function(){ | |
return new Function("a = 1", "b = 2", | |
"return a === 3 && b === 2;" | |
)(3); | |
} | |
// Rest Parameters | |
// basic functionality | |
function(){ | |
return (function (foo, ...args) { | |
return args instanceof Array && args + "" === "bar,baz"; | |
}("foo", "bar", "baz")); | |
} | |
// function length property | |
function(){ | |
return function(a, ...b){}.length === 1 && function(...c){}.length === 0; | |
} | |
// 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")); | |
} | |
// can't be used in setters | |
function(){ | |
return (function (...args) { | |
try { | |
eval("({set e(...args){}})"); | |
} catch(e) { | |
return true; | |
} | |
}()); | |
} | |
// New Function Support | |
function(){ | |
return new Function("a", "...b", | |
"return b instanceof Array && a+b === 'foobar,baz';" | |
)('foo','bar','baz'); | |
} | |
// Spread Operator | |
// with arrays, in function calls | |
function(){ | |
return Math.max(...[1, 2, 3]) === 3 | |
} | |
// with arrays, in array literals | |
function(){ | |
return [...[1, 2, 3]][2] === 3; | |
} | |
// with sparse Arrays in function calls | |
function(){ | |
var a = Array(...[,,]); | |
return "0" in a && "1" in a && '' + a[0] + a[1] === "undefinedundefined"; | |
} | |
// with sparse arrays in array literals | |
function(){ | |
var a = [...[,,]]; | |
return "0" in a && "1" in a && '' + a[0] + a[1] === "undefinedundefined"; | |
} | |
// with strings, in function calls | |
function(){ | |
return Math.max(..."1234") === 4; | |
} | |
// with strings, in array literals | |
function(){ | |
return ["a", ..."bcd", "e"][3] === "d"; | |
} | |
// with astral plane strings, in function calls | |
function(){ | |
return Array(..."𠮷𠮶")[0] === "𠮷"; | |
} | |
// with astral plane strings, in array literals | |
function(){ | |
return [..."𠮷𠮶"][0] === "𠮷"; | |
} | |
// with generator instances, in calls | |
function(){ | |
var iterable = (function*(){ yield 1; yield 2; yield 3; }()); | |
return Math.max(...iterable) === 3; | |
} | |
// with generator instances, in arrays | |
function(){ | |
var iterable = (function*(){ yield "b"; yield "c"; yield "d"; }()); | |
return ["a", ...iterable, "e"][3] === "d"; | |
} | |
// with generic iterables, in calls | |
function(){ | |
var iterable = global.__createIterableObject([1, 2, 3]); | |
return Math.max(...iterable) === 3; | |
} | |
// with generic iterables, in arrays | |
function(){ | |
var iterable = global.__createIterableObject(["b", "c", "d"]); | |
return ["a", ...iterable, "e"][3] === "d"; | |
} | |
// with instances of iterables, in calls | |
function(){ | |
var iterable = global.__createIterableObject([1, 2, 3]); | |
return Math.max(...Object.create(iterable)) === 3; | |
} | |
// with instances of iterables, in arrays | |
function(){ | |
var iterable = global.__createIterableObject(["b", "c", "d"]); | |
return ["a", ...Object.create(iterable), "e"][3] === "d"; | |
} | |
// spreading non-iterables is a runtime error | |
function(){ | |
try { | |
Math.max(...2); | |
} catch(e) { | |
return Math.max(...[1, 2, 3]) === 3; | |
} | |
} | |
// object literal extensions | |
// computed properties | |
function(){ | |
var x = 'y'; | |
return ({ [x]: 1 }).y === 1; | |
} | |
// shorthand properties | |
function(){ | |
var a = 7, b = 8, c = {a,b}; | |
return c.a === 7 && c.b === 8; | |
} | |
// shorthand methods | |
function(){ | |
return ({ y() { return 2; } }).y() === 2; | |
} | |
// string-keyed shorthand methods | |
function(){ | |
return ({ "foo bar"() { return 4; } })["foo bar"]() === 4; | |
} | |
// computed shorthand methods | |
function(){ | |
var x = 'y'; | |
return ({ [x](){ return 1 } }).y() === 1; | |
} | |
// 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'; | |
} | |
// for..of loops | |
// with arrays | |
function(){ | |
var arr = [5]; | |
for (var item of arr) | |
return item === 5; | |
} | |
// with sparse arrays | |
function(){ | |
var arr = [,,]; | |
var count = 0; | |
for (var item of arr) | |
count += (item === undefined); | |
return count === 2; | |
} | |
// with strings | |
function(){ | |
var str = ""; | |
for (var item of "foo") | |
str += item; | |
return str === "foo"; | |
} | |
// with astral plane strings | |
function(){ | |
var str = ""; | |
for (var item of "𠮷𠮶") | |
str += item + " "; | |
return str === "𠮷 𠮶 "; | |
} | |
// 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"; | |
} | |
// with generic iterables | |
function(){ | |
var result = ""; | |
var iterable = global.__createIterableObject([1, 2, 3]); | |
for (var item of iterable) { | |
result += item; | |
} | |
return result === "123"; | |
} | |
// 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"; | |
} | |
// 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; | |
} | |
// 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; | |
} | |
// octal and binary literals | |
// octal literals | |
function(){ | |
var a = "ba", b = "QUX"; | |
return `foo bar | |
${a + "z"} ${b.toLowerCase()}` === "foo bar\nbaz qux"; | |
} | |
// binary literals | |
function(){ | |
return 0b10 === 2 && 0B10 === 2; | |
} | |
// octal supported by Number() | |
function(){ | |
return Number('0o1') === 1; | |
} | |
// binary supported by Number() | |
function(){ | |
return Number('0b1') === 1; | |
} | |
// template literals |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment