Strict mode changes some previously-accepted mistakes into errors. JavaScript was designed to be easy for novice developers, and sometimes it gives operations which should be errors non-error semantics. Sometimes this fixes the immediate problem, but sometimes this creates worse problems in the future. Strict mode treats these mistakes as errors so that they're discovered and promptly fixed.
First, strict mode makes it impossible to accidentally create global variables. In normal JavaScript mistyping a variable in an assignment creates a new property on the global object and continues to "work" (although future failure is possible: likely, in modern JavaScript). Assignments, which would accidentally create global variables, instead throw an error in strict mode:
'use strict';
let mistypeVariable;
mistypeVarible = 17;
Second, strict mode makes assignments which would otherwise silently fail to throw an exception. For example, NaN
is a non-writable global variable. In normal code assigning to NaN
does nothing; the developer receives no failure feedback. In strict mode assigning to NaN
throws an exception. Any assignment that silently fails in normal code (assignment to a non-writable global or property, assignment to a getter-only property, assignment to a new property on a non-extensible object) will throw in strict mode:
'use strict';
var undefined = 5;
var Infinity = 5;
const obj1 = {};
Object.defineProperty(obj1, 'x', { value: 42, writable: false });
obj1.x = 9;
const obj2 = { get x() { return 17; } };
obj2.x = 5;
const fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = 'ohai';
Third, attempts to delete undeletable properties throw in strict mode (where before the attempt would have no effect):
'use strict';
delete Object.prototype;
Fourth, strict mode requires that function parameter names be unique. In normal code the last duplicated argument hides previous identically-named arguments. Those previous arguments remain available through arguments[i]
, so they're not completely inaccessible. Still, this hiding makes little sense and is probably undesirable (it might hide a typo, for example), so in strict mode duplicate argument names are a syntax error:
function sum(a, a, c) {
'use strict';
return a + a + c;
}
Fifth, strict mode forbids a 0
-prefixed octal literal or octal escape sequence. Outside strict mode, a number beginning with a 0
, such as 0644
, is interpreted as an octal number (0644 === 420
), if all digits are smaller than 8. Octal escape sequences, such as "\45"
, which is equal to "%"
, can be used to represent characters by extended-ASCII character code numbers in octal. In strict mode, this is a syntax error. The standardized way to denote octal literals is via the 0o
prefix. For example:
Novice developers sometimes believe a leading zero prefix has no semantic meaning, so they might use it as an alignment device — but this changes the number's meaning! A leading zero syntax for the octal is rarely useful and can be mistakenly used, so strict mode makes it a syntax error:
'use strict';
const sum = 015 +
197 +
142;
const sumWithOctal = 0o10 + 8;
console.log(sumWithOctal);
Sixth, strict mode forbids setting properties on primitive values. Without strict mode, setting properties is ignored (no-op), with strict mode, however, a TypeError
is thrown.
'use strict';
false.true = '';
(14).sailing = 'home';
'with'.you = 'far away';
Duplicate property names used to be considered a SyntaxError
in strict mode. With the introduction of computed property names, making duplication possible at runtime, this restriction was removed in ES2015.
'use strict';
const o = { p: 1, p: 2 };
Note: Making code that used to error become non-errors is always considered backwards-compatible. This is a good part of the language being strict about throwing errors: it leaves room for future semantic changes.