JS: Strict Mode - use strict | JavaScript

JavaScript Strict Mode - use strict

Strict Mode makes code compulsory to declare a variable before use.

JavaScript runs in Loose Mode by default. Since ECMAScript 5, Strict Mode introduced. In loose mode following code works fine:

j = 30;

But in Strict Mode following error message given:

ReferenceError: assignment to undeclared variable j
JavaScript works in Strict Mode if 'use strict' written at the beginning of the file or a the function.

How Strict Mode works

Add the following text (within quotes) at the top of the JavaScript file:

'use strict'

or add at top in the function body:

function test(){ 'use strict' var n = 60; }

Why 'use strict' as string

This looks odd that we declare the strict mode as string literal i.e. 'use strinct' instead of obvious way use strict or some likely keyword. The short answer is backward and forward compatibility. This is just because to let the JavaScript run fine if the browser etc. has some earlier version that does not support strict mode and thats it!.

Strict Mode Scope

strict mode can be for whole file or for one or more particular function(s).

File scope

'use strict' at the top of file applies to the global level as well as within functions.

'use strict'; x = 50; //error function multiple(){ y = 100; //error twoTimes = x * 2;//error, because towTimes is not declared with var or let }

Function scope

'use string' within a function impose restrictions for that function only.

g = 50; //valid: its in loose/dynamic mode at this point function test(){ 'use strict' //function in Strict Mode local = 100; //error: its in strict mode at this point } test(); Uncaught ReferenceError: local is not defined ReferenceError: assignment to undeclared variable local
If 'use strict' is not ommited, the file or function is called in default mode, loose mode or dynamic mode, all are valid names and used well in JavaScript prespective. If 'use strict' added at the top of the file or the function scope, the scope is call in Strict Mode.

Variable Declaration required

Either assigning a number, string or an object, must declare a variable before declare

'use strict' country = {name:'Egypt', capital:'Cairo'}; ReferenceError: country is not defined ReferenceError: assignment to undeclared variable country

Delete variable error

'use strict' var x = 50; delete x; //error Uncaught SyntaxError: Delete of an unqualified identifier in strict mode. SyntaxError: applying the 'delete' operator to an unqualified name is deprecated

Delete function error

'use strict' function f() {}; delete f; //error Uncaught SyntaxError: Delete of an unqualified identifier in strict mode. SyntaxError: applying the 'delete' operator to an unqualified name is deprecated

Duplicate parameter name error

'use strict' function f(p, p){ alert(p); }; Uncaught SyntaxError: Duplicate parameter name not allowed in this context SyntaxError: duplicate formal argument p

Octal literals error

Octal number literals with 0-prefix only throw error

'use strict' var y = 050; //error Uncaught SyntaxError: Octal literals are not allowed in strict mode. SyntaxError: "0"-prefixed octal literals and octal escape sequences are deprecated; for octal literals use the "0o" prefix instead
Octal assignment with zero prefix 050 have been deprecated. Now should use 0o (zero and o alphabet) 0o50 instead particularly in Firefox latest versions. 0o50 also works in Chrome. New Octal prefix (0o) works in Strict Mode. This applies to both Octal number literals and Octal escape sequences.

Octal 0o prefix in literal

Following Octal literal with 0o prefix is valid even in strict mode.

'use strict' var x = 0o50; //valid 40

Octal escape sequences error

Octal escape sequences with 0-prefix only throw error

'use strict' var x = '\050'; //error Uncaught SyntaxError: Octal escape sequences are not allowed in strict mode. SyntaxError: "0"-prefixed octal literals and octal escape sequences are deprecated; for octal literals use the "0o" prefix instead

Octal 0o prefix in escape sequences

Following Octal escape sequence with prefix 0o is valid even in strict mode.

'use strict' var x = '\0o50'; //valid 40

Assign to a read-only property error

'use strict' var ship = {name:'Titanic'}; Object.defineProperty(ship, "year", {value:1919, writable:false}); ship.year = 1920; //error TypeError: Cannot assign to read only property 'year' of object TypeError: "year" is read-only

Setting getter-only property error

Cannot set object property which has only a getter

'use strict' var ww2 = {get start() {return 1939} }; ww2.start = 1945; //error TypeError: Cannot set property start of # which has only a getter setting getter-only property "start"

Delete an undeletable property error

As some properties are undeletable particularly of JavaScript built-in, cause error in Strict Mode:

'use strict' delete Object.prototype; TypeError: Cannot delete property 'prototype' of function Object() { [native code] } TypeError: property "prototype" is non-configurable and can't be deleted

eval keyword as a variable error

eval is invalid to be declare as a variable name, cause error in Strict Mode:

'use strict' var eval = 1947; Uncaught SyntaxError: Unexpected eval or arguments in strict mode SyntaxError: 'eval' can't be defined or assigned to in strict mode code

arguments keyword as a variable error

arguments is invalid to be declare as a variable name, cause error in Strict Mode:

'use strict' var arguments = 1947; Uncaught SyntaxError: Unexpected eval or arguments in strict mode SyntaxError: 'arguments' can't be defined or assigned to in strict mode code

with statement in strict mode

With statement is invalid in strict mode because this makes the code more complex and invite bugs. with is not recommended in default/losse/dynamic mode here, cause error in Strict Mode

'use strict' with (Math){ alert(PI); } Uncaught SyntaxError: Strict mode code may not include a with statement SyntaxError: strict mode code may not contain 'with' statements

Scope of variables in eval() error

Variables declared within eval() are not accessible in the caller scope

'use strict' eval ("var x = 50"); alert (x); //error ReferenceError: x is not defined

this keyword behaviour

In 'use strict' mode, this keyword in a function is the reference of the caller object.

First check the this keyword in loose/dynamic mode (i.e. without 'use strict'):

function refLoose() { console.log(this); } refLoose(); Window

Now the reference of the this keyword in strict mode:

'use strict'; function refStrict() { console.log(this); } refStrict(); undefined

The result is same even if the function is in the strict mode only:

function refStrictFunc() { 'use strict'; console.log(this); } refStrictFunc(); undefined
Accessing variable without declaration or intialization will cause an error in Default Mode as well. The Strict Mode refrains from ommiting declaration keywords i.e. var, let or const.

How Strict Mode behaves

  • Variable declaration is mandatory
  • Can not delete a variable
  • Can not delete a function
  • Can not repeat function parameter name (in declaration)
  • Can not assign a octal number literal or escape sequence with 0-prefix, but 0o-prefix is valid
  • Can not assign value to read-only and get-only properties
  • Can not delete a undeletable property
  • Can not use eval or arguments as variable name in declaration
  • Can not use with statement
  • Can not use variables declared in eval() in caller scope
  • this refers the object who called that function

Notes

  1. Strict Mode improves the code readability
  2. Bugs are minimized, particularly those occoured due to spelling mistakes
  3. Testing become comparatively easier
  4. Strict mode must be defined at the top of the file for file scope
  5. Strict mode can be limited to particular function(s)
  6. 'use strict' is cause error if the JavaScript version on client/server machine is older due to bing string.

Conclusion

'use strict' is an good feature from programming prespective as this refrains from the inappropriate bugs and confusing code. Most of the feature e.g. mandatory declaration of variables, raising issues.