/* * Tests for declaration binding instantiation (E5 Section 10.5). */ /*=== 1 false 1 SyntaxError 1 false 1 SyntaxError function false function SyntaxError ===*/ /* Argument, function declaration, and variable bindings are * non-configurable (non-deletable) in function code. */ try { // binding not deletable, 'delete a' returns false (E5 Section 10.2.1.1.5, // step 3). eval("function func_arg1(a) { print(a); print(delete a); print(a); }"); func_arg1(1); } catch (e) { print(e.name); } try { // in strict mode, SyntaxError eval("function func_arg2(a) { 'use strict'; print(a); print(delete a); print(a); }"); func_arg2(1); } catch (e) { print(e.name); } try { eval("function func_var1() { var a = 1; print(a); print(delete a); print(a); }"); func_var1(); } catch (e) { print(e.name); } try { eval("function func_var2() { 'use strict'; var a = 1; print(a); print(delete a); print(a); }"); func_var2(); } catch (e) { print(e.name); } try { eval("function func_fun1() { function a() {}; print(typeof a); print(delete a); print(typeof a); }"); func_fun1(); } catch (e) { print(e.name); } try { eval("function func_fun2() { 'use strict'; function a() {}; print(typeof a); print(delete a); print(typeof a); }"); func_fun2(); } catch (e) { print(e.name); } /*=== 10 true ReferenceError function true undefined ===*/ /* Variable and function declarations established using a direct eval ARE deletable, * even in function code. */ try { eval("function func_var_eval1() { eval('var a = 10'); print(a); print(delete(a)); print(a); };"); func_var_eval1(); } catch (e) { print(e.name); } try { eval("function func_fun_eval1() { eval('function a() {}'); print(typeof a); print(delete(a)); print(typeof a); };"); func_fun_eval1(); } catch (e) { print(e.name, e.message); } /*=== true SyntaxError ===*/ /* Attempt to delete an unresolvable identifier reference returns true (!) in * non-strict mode, and is a SyntaxError in strict mode. */ try { eval("function func_unres1(a) { print(delete unresolvable); }"); func_unres1(1); } catch (e) { print(e.name); } try { eval("function func_unres2(a) { 'use strict'; print(delete unresolvable); }"); func_unres2(1); } catch (e) { print(e.name); } /*=== undefined undefined object ===*/ /* Arguments binding should exist for functions, not for global/eval code. * * Note: 'typeof foo' where 'foo' is an undefined variable is NOT a * ReferenceError but returns undefined. See E5 Section 11.4.3, step 2.a. * * Note: Rhino has 'arguments' bound in global code. */ try { // global print(typeof arguments); } catch (e) { print(e.name); } try { // eval embedded in global print(eval("typeof arguments")); } catch (e) { print(e.name); } try { // function eval("function foo() { print(typeof arguments); }; foo();"); } catch (e) { print(e.name); } /*=== object number SyntaxError ===*/ /* An arguments binding is mutable for non-strict code, immutable for strict code. * * Attempt to assign to arguments is a SyntaxError in strict code, so this is * actually pretty difficult to test :-). Even direct eval in strict code * creates a separate variable environment. */ function arguments_mutability1() { print(typeof arguments); arguments = 1; print(typeof arguments); } try { arguments_mutability1(); } catch (e) { print(e.name); } try { eval("function arguments_mutability2() {\n" + " 'use strict';\n" + " print(typeof arguments);\n" + " arguments = 1;\n" + " print(typeof arguments);\n" + "}"); } catch (e) { print(e.name); }