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.
Assigning to undeclared variables
Strict mode makes it impossible to accidentally create global variables. In sloppy mode, mistyping a variable in an assignment creates a new property on the global object and continues to "work". Assignments which would accidentally create global variables throw an error in strict mode:
"use strict";
let mistypeVariable;
mistypeVarible = 17;
Failing to assign to object properties
Strict mode makes assignments which would otherwise silently fail to throw an exception. There are three ways to fail a property assignment:
- assignment to a non-writable data property
- assignment to a getter-only accessor property
- assignment to a new property on a non-extensible object
For example, NaN
is a non-writable global variable. In sloppy mode, assigning to NaN
does nothing; the developer receives no failure feedback. In strict mode, assigning to NaN
throws an exception.
"use strict";
undefined = 5;
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";
Failing to delete object properties
Attempts to delete a non-configurable or otherwise undeletable (e.g. it's intercepted by a proxy's deleteProperty
handler which returns false
) property throw in strict mode (where before the attempt would have no effect):
"use strict";
delete Object.prototype;
delete [].length;
Strict mode also forbids deleting plain names. delete name
in strict mode is a syntax error:
"use strict";
var x;
delete x;
If the name is a configurable global property, prefix it with globalThis
to delete it.
"use strict";
delete globalThis.x;
Duplicate parameter names
Strict mode requires that function parameter names be unique. In sloppy mode, the last duplicated argument hides previous identically-named arguments. Those previous arguments remain available through arguments
, 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;
}
Legacy octal literals
Strict mode forbids a 0
-prefixed octal literal or octal escape sequence. In sloppy 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. 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;
The standardized way to denote octal literals is via the 0o
prefix. For example:
const sumWithOctal = 0o10 + 8;
console.log(sumWithOctal);
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. More formally, it's disallowed to have \
followed by any decimal digit other than 0
, or \0
followed by a decimal digit; for example \9
and \07
.
Setting properties on primitive values
Strict mode forbids setting properties on primitive values. Accessing a property on a primitive implicitly creates a wrapper object that's unobservable, so in sloppy mode, setting properties is ignored (no-op). In strict mode, a TypeError
is thrown.
"use strict";
false.true = "";
(14).sailing = "home";
"with".you = "far away";
Duplicate property names
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.