| |
| Test 1: Simple case with single block-scoped function |
| |
| undefined |
| function f() { } |
| function f() { } |
| function g() { } |
| function g() { } |
| function h() { } |
| |
| Test 2: Block-scoped function shadows outer let binding, but leaks into function scope |
| |
| undefined |
| let f |
| function f() { } |
| let f |
| function f() { } |
| |
| Test 3: Assignment to function in block behaves like assigning let variable; function still leaks out to function scope; assignment does not affect function scope binding |
| |
| undefined |
| let f |
| reassigned inner function declared "let" f |
| let f |
| reassigned outer let f |
| function f() { } |
| |
| Test 4: Last executed declaration wins; simple case |
| |
| function f(one) { } |
| function f(one) { } |
| function f(two) { } |
| function f(two) { } |
| |
| Test 5: Inner shadows outer and last executed (inner) wins for function scope |
| |
| function f(outer) { } |
| function f(inner) { } |
| function f(outer) { } |
| function f(inner) { } |
| |
| Test 6: Last declaration executed wins; loop and conditionals |
| |
| undefined |
| undefined |
| function f(one) { } |
| function f(one) { } |
| function f(one) { } |
| function f(two) { } |
| function f(two) { } |
| function f(two) { } |
| function f(one) { } |
| function f(one) { } |
| function f(one) { } |
| |
| Test 7: Make sure function scope binding is initialized even when it is an activation object (imposed by presence of eval) |
| |
| undefined |
| function f() { } |
| function f() { } |
| |
| Test 8: Function scope binding does not occur in strict mode |
| |
| ReferenceError: 'f' is undefined |
| function f() { } |
| ReferenceError: 'f' is undefined |
| |
| Test 9: Overwriting user declared var |
| |
| var f |
| function f() { } |
| function f() { } |
| |
| Test 10: inner functions before block scope function should bind to function scoped binding, not outer scope |
| |
| undefined |
| inner block-scope f() |
| |
| Test 11: Function declarations shadow with object but also do not assign to with object properties |
| |
| undefined |
| undefined |
| function f() { } |
| function g() { } |
| with g |
| function h() { } |
| function f() { } |
| function g() { } |
| function h() { } |
| |
| Test 12: Ensure redeclaration errors do not occur with var binding of block scoped functions |
| |
| let f |
| function f() { } |
| function g() { } |
| let f |
| let g |
| |
| Test 13: Eval does not leak let and const bindings |
| |
| var f |
| ReferenceError: 'g' is undefined |
| eval var f |
| function g() { } |
| ReferenceError: 'h' is undefined |
| ReferenceError: 'i' is undefined |
| eval blockscoped var j |
| ReferenceError: 'k' is undefined |
| |
| Test 14: Eval leaks vars, and var declarations bind to block scoped bindings for rhs initialization |
| |
| eval var f |
| eval var g |
| eval var f |
| eval var g |
| var f |
| eval var g |
| |
| Test 15: Eval should have TDZ use before declaration error |
| |
| ReferenceError: Use before declaration |
| |
| Test 16: Eval function declarations create/assign to a var binding and assign to let binding, and create a let binding if not at eval global scope |
| |
| function h(ineval) { } |
| function h(notineval) { } |
| function f(ineval) { } |
| function g(ineval) { } |
| function h(notineval) { } |
| function f(ineval) { } |
| function g(ineval) { } |
| function h(ineval) { } |
| |
| Test 17: var initializations should find block scoped lets but still create properties at function scope |
| |
| var f in eval |
| var g in eval |
| var f in eval |
| undefined |
| |
| Test 18: function declaration in eval should shadow variables declared outside eval (strict) |
| |
| function f() { } |
| function g() { } |
| let g |
| var f |
| ReferenceError: 'g' is undefined |
| |
| Test 19: function declaration var binding should be ignored when same named let/const variable is at function scope |
| |
| function f() { } |
| let f |
| function g() { } |
| const g |
| function h() { } |
| function h() { } |
| function i() { } |
| let i |
| function j() { } |
| const j |
| function k() { } |
| var k |
| function l(one) { } |
| function l(one) { } |
| function l(one) { } |
| function l(two) { } |
| function l(two) { } |
| outer let l |
| TypeError: Assignment to const |
| const m |
| const m |
| TypeError: Assignment to const |
| inner const m |
| const m |
| function m(three) { } |
| function m(three) { } |
| const m |
| function n() { } |
| function n() { } |
| function n() { } |
| ReferenceError: Use before declaration |
| let o |
| TypeError: Assignment to const |
| const p |
| function q() { } |
| var q |
| |
| Test 20: Function declaration in statement context without {} |
| |
| 1 |
| 0 |
| 1 |
| 0 |
| |
| Test 21: Function declaration in statement context without {}, strict mode |
| |
| 21.1: Syntax error |
| 21.2: Syntax error |
| 21.3: Syntax error |
| 21.4: Syntax error |
| |
| Test 22: Function declaration in statement context without {}, illegal in sloppy mode |
| |
| 22.1: Syntax error |
| 22.2: Syntax error |
| 22.3: Syntax error |
| 22.4: Syntax error |
| 22.5: Syntax error |
| 22.6: Syntax error |
| 22.7: Syntax error |
| 22.8: Syntax error |
| 22.8: Syntax error |
| |
| Test Global: Global scope has the same semantics for block-scoped function declarations |
| |
| undefined |
| function glo_f() { } |
| function glo_f() { } |
| function glo_g(globalscope) { } |
| function glo_g(blockscope) { } |
| function glo_g(blockscope) { } |
| undefined |
| function glo_h(one) { } |
| function glo_h(one) { } |
| function glo_h(two) { } |
| function glo_h(two) { } |
| |
| Global version of Test 19: function declaration's var binding should be ignored when same named let/const variable is at global scope |
| |
| function glo_t19_f() { } |
| let glo_t19_f |
| function glo_t19_g() { } |
| const glo_t19_g |
| function glo_t19_h() { } |
| function glo_t19_h() { } |
| function glo_t19_i() { } |
| let glo_t19_i |
| function glo_t19_j() { } |
| const glo_t19_j |
| function glo_t19_k() { } |
| var glo_t19_k |
| function glo_t19_l(one) { } |
| function glo_t19_l(one) { } |
| function glo_t19_l(one) { } |
| undefined |
| function glo_t19_l(two) { } |
| function glo_t19_l(two) { } |
| outer let glo_t19_l |
| undefined |
| TypeError: Assignment to const |
| const glo_t19_m |
| const glo_t19_m |
| undefined |
| TypeError: Assignment to const |
| inner const m |
| const glo_t19_m |
| undefined |
| function glo_t19_m(three) { } |
| function glo_t19_m(three) { } |
| const glo_t19_m |
| undefined |
| function glo_t19_n() { } |
| function glo_t19_n() { } |
| function glo_t19_n() { } |
| ReferenceError: Use before declaration |
| let glo_t19_o |
| TypeError: Assignment to const |
| const glo_t19_p |
| function glo_t19_q() { } |
| var glo_t19_q |
| ReferenceError: Invalid left-hand side in assignment |