/* * Various directive prologue tests. * * How to detect whether strict mode is enabled? This can be done * through any strict mode feature. One very simple one is this: * strict functions don't get a 'this' binding when invoked, whereas * 'this' binding for non-strict functions is the global object. * * Thus, the following prints true when executed inside a strict mode * function: * * print(!this); * */ /*=== false true false true false true ===*/ /* Basic test for strict mode directive. */ function f_nostrict() { print(!this); } function f_strict() { 'use strict'; print(!this); } function f_nostrict_escape() { /* escaped characters are significant for directives: the expression * below is a directive, but not a valid 'use strict' directive. */ 'use\u0020strict'; print(!this); } function f_strict_escape() { /* the first directive is ignored, the second is still processed (we're * still in the directive prologue). */ 'use\u0020strict'; // not a 'use strict' directive, but still a valid directive 'use strict'; // but this is print(!this); } function f_nostrict_plain_string_only() { /* to be part of the directive prologue, the expression must be a plain * string with no parens etc. */ ('use strict'); // not a valid 'use strict' directive, terminates prologue 'use strict'; // no longer a 'use strict' directive, not inside prologue print(!this); } function f_strict_comments_ok() { /* comments and whitespace don't affect directive prologue parsing */ 'use strict' /* comment */; print(!this); } f_nostrict(); f_strict(); f_nostrict_escape(); f_strict_escape(); f_nostrict_plain_string_only(); f_strict_comments_ok(); /*=== false ===*/ /* This was broken at some point: unless the first statement parsing had * finished, the "in directive prologue" flag would be incorrectly set * for a nested statement. */ function f_nostrict_nested() { try { 'use strict'; // should have no effect } catch (e) { } print(!this); } f_nostrict_nested(); /*=== use strict use strict ===*/ /* Although directives are special, they are still valid expression statements * and must generate an implicit return value for e.g. eval(). */ try { print(eval("'use strict';")); print(eval("'use strict'; var x = 10;")); // var statement is empty, no effect } catch (e) { print(e.name); }