Note for Strict Mode in ECMA-262-5
Reason
1. provide more thorough error checking
2. avoid error-prone constructs
3. clarifies many ambiguities in the 3rd edition specification
4. others make ECMAScript code more robust
Common ways
1. strict script
// before any code
"use strict";
var v = "I'm a strict code";
2. strict function
function foo() {
"use strict";
return "I'm a strict function";
}
Changes
1. impossible to accidentally create global variables
"use strict";
mistypedVariable = 1; // throws a ReferenceError
2. makes assignments which would otherwise silently fail throw an exception
"use strict";
NaN = true; // throws TypeError: Cannot assign to read only 'NaN' in strict mode
var obj1 = {};
Object.defineProperty(obj1, "x", {value:1, writable:false});
obj1.x = 9;console.log(obj1.x);}() // throws a TypeError
var obj2 = { get x() {return 17;} };
obj2.x = 5; // throws a TypeError
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = "hello"; // throws a TypeError
3. makes attempts to delete undeletable properties throw
"use strict";
delete Object.prototype; // throws a TypeError
4. forbids duplicated variables in function arguments or object properties.
"use strict";
var o = {p : 1, p:2}; // syntax error
function sum(a, a, c) { // syntax error
"use strict";
return a + b + c;
}
5. forbids octal syntax (for optimization)
"use strict";
var x = 17;
with (obj) {// syntax error
x;
}
6. eval of strict mode doesn't introduce new variables into the surrounding scope
var x = 17;
var evalX = eval("'use strict'; var x = 42; x");
assert(x === 17);
assert(evalX === 42);
7. some disgusting and complex conditions
function strict1(str) {
"use strict";
return eval(str); // str will be treated as strict mode code
}
function strict2(f, str) {
"use strict";
return f(str); // not eval(…): str is strict if and only if it invokes strict mode
}
function nonstrict(str) {
return eval(str); // str is strict if and only if it invokes strict mode
}
strict1("'Strict mode code!'");
strict1("'use strict'; 'Strict mode code!'");
strict2(eval, "'Non-strict code.'");
strict2(eval, "'use strict'; 'Strict mode code!'");
nonstrict("'Non-strict code.'");
nonstrict("'use strict'; 'Strict mode code'");
8. forbids deleting plain names
"use strict";
eval("var x; delete x;"); // syntax error
9. the names eval and arguments can't be bound or assigned in languae syntax. All these attempts to do so are syntax errors.
"use strict";
eval = 17;
arguments++;
++eval;
var obj = {set p(arguments){}};
var eval;
try {} catch(arguments){}
function x(eval){}
function arguments(){}
var y = function eval(){}
var f = new Function("arguments", "'use strict'; return 17;");
10. cancelled arguments binding
function f(a) {
"use strict";
a = 42;
return [a, arguments[0]];
}
var pair = f(17);
assert(pair[0] === 42);
assert(pair[1] === 17);
11. arguments.callee is no longer supported
"use strict";
var f = function() {return arguments.callee;};
f(); // throws a TypeError
12. changes on this binding
precondition: function assert(b) {console.log(b);}
test in firebug:
13. both funObj.caller and funcObj.arguments are non-deletable properties which throw when set or retrieved:
function restricted() {
"use strict";
restricted.caller; // throws a TypeError
restricted.arguments; // throws a TypeError
}
function privilegedInvoker() {
return restricted();
}
privilegedInvoker();
14. arguments.caller (not implemented) also a non-deletable property which throws when set or retrieved:
"use strict";
function fun(a, b) {
"use strict";
var v = 12;
return arguments.caller; // throws a TypeError
}
fun(1, 2);
15. Reserved names: can't name or use variables or arguments with these names: implements, interface, let, package, private, protected, public, static and yield.
function package(protected) {// syntax error
"use strict";
var implements; // syntax error
interface: // syntax error
while(true) {
break interface; // syntax error
}
function private() {} // syntax error
}
function fun(static) {'use strict';}// syntax error
16. functions can only be declared at top level or immediately within another function
"use strict";
if (true) {
function f() {}; // syntax error
f();
}
for (var i = 0; i < 5; i++) {
function f2() {}; // syntax error
f2();
}
function baz() { // ok
function eit() {} // ok as well
}
REFERENCE: