JavaScript's strict mode, introduced in ECMAScript 5, is a way to to a restricted variant of JavaScript, thereby implicitly opting-out of " ". Strict mode isn't just a subset: it has different semantics from normal code. Browsers not supporting strict mode will run strict mode code with different behavior from browsers that do, so don't rely on strict mode without feature-testing for support for the relevant aspects of strict mode. Strict mode code and non-strict mode code can coexist, so scripts can opt into strict mode incrementally. opt in sloppy mode intentionally Strict mode makes several changes to normal JavaScript semantics: Eliminates some JavaScript silent errors by changing them to throw errors. Fixes mistakes that make it difficult for JavaScript engines to perform optimizations: strict mode code can sometimes be made to run faster than identical code that's not strict mode. Prohibits some syntax likely to be defined in future versions of ECMAScript. See , if you want to change your code to work in the restricted variant of JavaScript. transitioning to strict mode Invoking strict mode Strict mode applies to or to . It doesn't apply to block statements enclosed in braces; attempting to apply it to such contexts does nothing. code, code, event handler attributes, strings passed to , and related functions are entire scripts, and invoking strict mode in them works as expected. entire scripts individual functions {} eval Function WindowTimers.setTimeout() To invoke strict mode for an entire script, put the statement (or ) before any other statements. Strict mode for scripts exact "use strict"; 'use strict'; ; v = ; // Whole-script strict mode syntax 'use strict' var "Hi! I'm a strict mode script!" This syntax has a trap that has : it isn't possible to blindly concatenate conflicting scripts. Consider concatenating a strict mode script with a non-strict mode script: the entire concatenation looks strict! The inverse is also true: non-strict plus strict looks non-strict. Obviously, concatenation of scripts is never ideal, but if you must, consider enabling strict on a function-by-function basis. already bitten a major site You can also take the approach of wrapping the entire contents of a script in a function and having that outer function use strict mode. This eliminates the concatenation problem and it means that you have to explicitly export any shared variables out of the function scope. Likewise, to invoke strict mode for a function, put the statement (or ) in the function's body before any other statements. Strict mode for functions exact "use strict"; 'use strict'; { ; { ; } + nested(); } { ; } ( ) function strict // Function-level strict mode syntax 'use strict' ( ) function nested return 'And so am I!' return "Hi! I'm a strict mode function! " ( ) function notStrict return "I'm not strict." ECMAScript 2015 introduced and therefore a 3rd way to enter strict mode. The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it. Strict mode for modules JavaScript modules { } strict; ( ) function strict // because this is a module, I'm strict by default export default Changes in strict mode Strict mode changes both syntax and runtime behavior. Changes generally fall into these categories: changes converting mistakes into errors (as syntax errors or at runtime), changes simplifying how the particular variable for a given use of a name is computed, changes simplifying and , changes making it easier to write "secure" JavaScript, and changes anticipating future ECMAScript evolution. eval arguments 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. Converting mistakes into errors 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: ; mistypeVariable = ; 'use strict' // Assuming no global variable mistypedVariable exists 17 // this line throws a ReferenceError due to the // misspelling of variable Second, strict mode makes assignments which would otherwise silently fail to throw an exception. For example, is a non-writable global variable. In normal code assigning to does nothing; the developer receives no failure feedback. In strict mode assigning to 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 object) will throw in strict mode: NaN NaN NaN non-extensible ; = ; = ; obj1 = {}; .defineProperty(obj1, , { : , : }); obj1.x = ; obj2 = { get x() { ; } }; obj2.x = ; fixed = {}; .preventExtensions(fixed); fixed.newProp = ; 'use strict' // Assignment to a non-writable global var undefined 5 // throws a TypeError var Infinity 5 // throws a TypeError // Assignment to a non-writable property var Object 'x' value 42 writable false 9 // throws a TypeError // Assignment to a getter-only property var return 17 5 // throws a TypeError // Assignment to a new property on a non-extensible object var Object 'ohai' // throws a TypeError Third, strict mode makes attempts to delete undeletable properties throw (where before the attempt would simply have no effect): ; .prototype; 'use strict' delete Object // throws a TypeError Fourth, strict mode prior to Gecko 34 requires that all properties named in an object literal be unique. The normal code may duplicate property names, with the last one determining the property's value. But since only the last one does anything, the duplication is simply a vector for bugs, if the code is modified to change the property value other than by changing the last instance. Duplicate property names are a syntax error in strict mode: This is no longer the case in ECMAScript 2015 ( ). bug 1041128 ; o = { : , : }; 'use strict' var p 1 p 2 // !!! syntax error Fifth, 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 , 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: arguments[i] { ; a + a + c; } ( ) function sum a, a, c // !!! syntax error 'use strict' return // wrong if this code ran Sixth, a strict mode in ECMAScript 5 forbids octal syntax. The octal syntax isn't part of ECMAScript 5, but it's supported in all browsers by prefixing the octal number with a zero: and . In ECMAScript 2015 Octal number is supported by prefixing a number with " ". i.e. 0644 === 420 "\045" === "%" 0o a = ; var 0o10 // ES2015: Octal Novice developers sometimes believe a leading zero prefix has no semantic meaning, so they use it as an alignment device — but this changes the number's meaning! A leading zero syntax for the octals is rarely useful and can be mistakenly used, so strict mode makes it a syntax error: ; sum = + + ; sumWithOctal = + ; .log(sumWithOctal); 'use strict' var 015 // !!! syntax error 197 142 var 0o10 8 console // 16 Seventh, strict mode in ECMAScript 2015 forbids setting properties on values. Without strict mode, setting properties is simply ignored (no-op), with strict mode, however, a is thrown. primitive TypeError ( { ; .true = ; ( ).sailing = ; .you = ; })(); ( ) function 'use strict' false '' // TypeError 14 'home' // TypeError 'with' 'far away' // TypeError Strict mode simplifies how variable names map to particular variable definitions in the code. Many compiler optimizations rely on the ability to say that variable is stored in location: this is critical to fully ptimizing JavaScript code. JavaScript sometimes makes this basic mapping of name to variable definition in the code impossible to perform until runtime. Strict mode removes most cases where this happens, so the compiler can better optimize strict mode code. Simplifying variable uses X that First, strict mode prohibits . The problem with is that any name inside the block might map either to a property of the object passed to it, or to a variable in surrounding (or even global) scope, at runtime: it's impossible to know which beforehand. Strict mode makes a syntax error, so there's no chance for a name in a to refer to an unknown location at runtime: with with with with ; x = ; (obj) { x; } 'use strict' var 17 with // !!! syntax error // If this weren't strict mode, would this be var x, or // would it instead be obj.x? It's impossible in general // to say without running the code, so the name can't be // optimized. The simple alternative of assigning the object to a short name variable, then accessing the corresponding property on that variable, stands ready to replace with. Second, . In normal code introduces a variable into the surrounding function or the global scope. This means that, in general, in a function containing a call to every name not referring to an argument or local variable must be mapped to a particular definition at runtime (because that might have introduced a new variable that would hide the outer variable). In strict mode creates variables only for the code being evaluated, so can't affect whether a name refers to an outer variable or some local variable: of strict mode code does not introduce new variables into the surrounding scope eval eval("var x;") x eval eval eval eval x = ; evalX = ( ); .assert(x === ); .assert(evalX === ); var 17 var eval "'use strict'; var x = 42; x;" console 17 console 42 If the function is invoked by an expression of the form in strict mode code, the code will be evaluated as strict mode code. The code may explicitly invoke strict mode, but it's unnecessary to do so. eval eval(...) { ; (str); } { ; f(str); } { (str); } strict1( ); strict1( ); strict2( , ); strict2( , ); nonstrict( ); nonstrict( ); ( ) function strict1 str 'use strict' return eval // str will be treated as strict mode code ( ) function strict2 f, str 'use strict' return // not eval(...): str is strict if and only // if it invokes strict mode ( ) function nonstrict str return eval // str is strict if and only // if it invokes strict mode "'Strict mode code!'" "'use strict'; 'Strict mode code!'" eval "'Non-strict code.'" eval "'use strict'; 'Strict mode code!'" "'Non-strict code.'" "'use strict'; 'Strict mode code!'" Thus names in strict mode code behave identically to names in strict mode code not being evaluated as the result of . eval eval Third, strict mode forbids deleting plain names. in strict mode is a syntax error: delete name ; x; x; ( ); 'use strict' var delete // !!! syntax error eval 'var y; delete y;' // !!! syntax error Strict mode makes and less bizarrely magical. Both involve a considerable amount of magical behavior in normal code: to add or remove bindings and to change binding values, and by its indexed properties aliasing named arguments. Strict mode makes great strides toward treating and as keywords, although full fixes will not come until a future edition of ECMAScript. Making eval and arguments simpler arguments eval eval arguments eval arguments First, the names and can't be bound or assigned in language syntax. All these attempts to do so are syntax errors: eval arguments ; = ; ++; ++ ; obj = { set p( ) { } }; ; { } ( ) { } { } { } y = { }; f = ( , ); 'use strict' eval 17 arguments eval var arguments var eval try catch arguments ( ) function x eval ( ) function arguments var ( ) function eval var new Function 'arguments' "'use strict'; return 17;" Second, strict mode code doesn't alias properties of objects created within it. In normal code within a function whose first argument is , setting also sets , and vice versa (unless no arguments were provided or is deleted). objects for strict mode functions store the original arguments when the function was invoked. does not track the value of the corresponding named argument, nor does a named argument track the value in the corresponding . arguments arg arg arguments[0] arguments[0] arguments arguments[i] arguments[i] { ; a = ; [a, [ ]]; } pair = f( ); .assert(pair[ ] === ); .assert(pair[ ] === ); ( ) function f a 'use strict' 42 return arguments 0 var 17 console 0 42 console 1 17 Third, is no longer supported. In normal code refers to the enclosing function. This use case is weak: simply name the enclosing function! Moreover, substantially hinders optimizations like inlining functions, because it must be made possible to provide a reference to the un-inlined function if is accessed. for strict mode functions is a non-deletable property which throws an error when set or retrieved: arguments.callee arguments.callee arguments.callee arguments.callee arguments.callee ; f = { .callee; }; f(); 'use strict' var ( ) function return arguments // throws a TypeError "Securing" JavaScript Strict mode makes it easier to write "secure" JavaScript. Some websites now provide ways for users to write JavaScript which will be run by the website . JavaScript in browsers can access the user's private information, so such JavaScript must be partially transformed before it is run, to censor access to forbidden functionality. JavaScript's flexibility makes it effectively impossible to do this without many runtime checks. on behalf of other users Certain language functions are so pervasive that performing runtime checks has a considerable performance cost. A few strict mode tweaks, plus requiring that user-submitted JavaScript be strict mode code and that it be invoked in a certain manner, substantially reduce the need for those runtime checks. First, the value passed as to a function in strict mode is not forced into being an object (a.k.a. "boxed"). For a normal function, is always an object: either the provided object if called with an object-valued ; the value, boxed, if called with a Boolean, string, or number ; or the global object if called with an or . (Use , , or to specify a particular .) this this this this undefined null this call apply bind this Not only is automatic boxing a performance cost, but exposing the global object in browsers is a security hazard because the global object provides access to functionality that "secure" JavaScript environments must restrict. Thus for a strict mode function, the specified is not boxed into an object, and if unspecified, will be : this this undefined ; { ; } .assert(fun() === ); .assert(fun.call( ) === ); .assert(fun.apply( ) === ); .assert(fun.call( ) === ); .assert(fun.bind( )() === ); 'use strict' ( ) function fun return this console undefined console 2 2 console null null console undefined undefined console true true That means, among other things, that in browsers it's no longer possible to reference the object through inside a strict mode function. window this Second, in strict mode it's no longer possible to "walk" the JavaScript stack via commonly-implemented extensions to ECMAScript. In normal code with these extensions, when a function fun is in the middle of being called, is the function that most recently called , and is the for that invocation of . fun.caller fun fun.arguments arguments fun Both extensions are problematic for "secure" JavaScript because they allow "secured" code to access "privileged" functions and their (potentially unsecured) arguments. If fun is in strict mode, both and are non-deletable properties which throw when set or retrieved: fun.caller fun.arguments { ; restricted.caller; restricted.arguments; } { restricted(); } privilegedInvoker(); ( ) function restricted 'use strict' // throws a TypeError // throws a TypeError ( ) function privilegedInvoker return Third, for strict mode functions no longer provide access to the corresponding function call's variables. In some old ECMAScript implementations was an object whose properties aliased variables in that function. This is a because it breaks the ability to hide privileged values via function abstraction; it also precludes most optimizations. arguments arguments.caller security hazard For these reasons no recent browsers implement it. Yet because of its historical functionality, for a strict mode function is also a non-deletable property which throws when set or retrieved: arguments.caller ; { ; v = ; .caller; } fun( , ); 'use strict' ( ) function fun a, b 'use strict' var 12 return arguments // throws a TypeError 1 2 // doesn't expose v (or a or b) Paving the way for future ECMAScript versions Future ECMAScript versions will likely introduce new syntax, and strict mode in ECMAScript 5 applies some restrictions to ease the transition. It will be easier to make some changes if the foundations of those changes are prohibited in strict mode. First, in strict mode, a short list of identifiers become reserved keywords. These words are , , , , , , , , and . In strict mode, then, you can't name or use variables or arguments with these names. implements interface let package private protected public static yield { ; implements; interface: ( ) { interface; } { } } { ; } ( ) function package protected // !!! 'use strict' var // !!! // !!! while true break // !!! ( ) function private // !!! ( ) function fun static 'use strict' // !!! Two Mozilla-specific caveats: First, if your code is JavaScript 1.7 or greater (for example in chrome code or when using the right ) and is strict mode code, and have the functionality they've had since those keywords were first introduced. <script type=""> let yield But strict mode code on the web, loaded with or , won't be able to use as identifiers. Second, while ES5 unconditionally reserves the words , , , , , and , before Firefox 5 Mozilla reserved them only in strict mode. <script src=""> <script>...</script> let/yield class enum export extends import super Second, . In normal mode in browsers, function statements are permitted "everywhere". It's an extension with incompatible semantics in different browsers. Note that function statements outside top level are permitted in ES2015. strict mode prohibits function statements, not at the top level of a script or function This is not part of ES5 (or even ES3)! ; ( ) { { } f(); } ( i = ; i < ; i++) { { } f2(); } { { } } 'use strict' if true ( ) function f // !!! syntax error for var 0 5 ( ) function f2 // !!! syntax error ( ) function baz // kosher ( ) function eit // also kosher This prohibition isn't strict mode proper because such function statements are an extension of basic ES5. But it is the recommendation of the ECMAScript committee, and browsers will implement it. Strict mode in browsers The major browsers now implement strict mode. However, don't blindly depend on it since there still are numerous or do not support it at all (e.g. Internet Explorer below version 10!). Relying on those changes will cause mistakes and errors in browsers which don't implement strict mode. Browser versions used in the wild that only have partial support for strict mode Strict mode changes semantics. Exercise caution in using strict mode, and back up reliance on strict mode with feature tests that check whether relevant parts of strict mode are implemented. Finally, make sure to . If you test only in browsers that don't support strict mode, you're very likely to have problems in browsers that do, and vice versa. test your code in browsers that do and don't support strict mode Specifications ECMAScript (ECMA-262) The definition of 'Strict Mode Code' in that specification. See also Where's Walden? » New ES5 strict mode support: now with poison pills! Where's Walden? » New ES5 strict mode requirement: function statements not at top level of a program or function are prohibited Where's Walden? » New ES5 strict mode support: new vars created by strict mode eval code are local to that code only JavaScript "use strict" tutorial for beginners. John Resig - ECMAScript 5 Strict Mode, JSON, and More ECMA-262-5 in detail. Chapter 2. Strict Mode. Strict mode compatibility table Transitioning to strict mode Credits Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode Published under license Open CC Attribution ShareAlike 3.0 Image: https://nhidev.github.io/JavaScript-Strict-Mode