| function assert(b) { |
| if (!b) |
| throw new Error("Bad assertion") |
| } |
| noInline(assert); |
| |
| function test(f, count = 1000) { |
| for (let i = 0; i < count; i++) |
| f(); |
| } |
| |
| function arr() { |
| return [10, 20, 30, 40]; |
| } |
| noInline(arr); |
| |
| let o = {}; |
| function arr2() { |
| return [10, 20, 30, [40, 50, o]]; |
| } |
| noInline(arr); |
| |
| function eq(a, b) { |
| // This only works for arrays with nested arrays in them, and numbers or anything else strict equal to each other. |
| if (!(a instanceof Array)) |
| return a === b; |
| |
| if (a.length !== b.length) |
| return false; |
| |
| for (let i = 0; i < a.length; i++) { |
| let e1 = a[i]; |
| let e2 = b[i]; |
| if (!eq(e1, e2)) |
| return false; |
| } |
| |
| return true; |
| } |
| |
| test(function() { |
| let [...[...x]] = arr(); |
| assert(eq(x, arr())); |
| }); |
| |
| test(function() { |
| let [ , , , [...e]] = arr2(); |
| assert(eq(e, [40, 50, o])); |
| }); |
| |
| test(function() { |
| let [ , , , ...e] = arr2(); |
| assert(eq(e[0], [40, 50, o])); |
| }); |
| |
| test(function() { |
| let [ , , , ...e] = arr2(); |
| assert(eq(e[0], [40, 50, o])); |
| }); |
| |
| function* gen() { |
| yield [1,2,3]; |
| yield 20; |
| yield 30; |
| yield 40; |
| } |
| |
| test(function() { |
| let [a, b, ...[...c]] = gen(); |
| assert(eq(a, [1,2,3])); |
| assert(b === 20); |
| assert(eq(c, [30, 40])); |
| }); |
| |
| test(function() { |
| let [[a, ...d], b, ...[...c]] = gen(); |
| assert(a === 1); |
| assert(eq(d, [2,3])); |
| assert(b === 20); |
| assert(eq(c, [30, 40])); |
| }); |
| |
| let called = false; |
| function fakeGen() { |
| return { |
| [Symbol.iterator]: function() { |
| let count = 0; |
| return { |
| next() { |
| called = true; |
| count++; |
| if (count === 1) |
| return {done: false, value: 50}; |
| return {done: true}; |
| } |
| }; |
| } |
| }; |
| } |
| |
| test(function() { |
| called = false; |
| let [...x] = fakeGen(); |
| assert(eq(x, [50])); |
| assert(called); |
| called = false; |
| }); |