0% found this document useful (0 votes)
3 views7 pages

Why Use Strict Directive

JavaScript's strict mode, introduced in ECMAScript 5, enhances code quality by enforcing stricter parsing and error handling, which helps prevent common coding pitfalls. It can be enabled globally or at the function level using the 'use strict' directive, and it introduces various restrictions, such as disallowing implicit global variable declarations and the use of certain keywords. Overall, strict mode promotes better programming practices and improves code maintainability.

Uploaded by

webcomputer06
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views7 pages

Why Use Strict Directive

JavaScript's strict mode, introduced in ECMAScript 5, enhances code quality by enforcing stricter parsing and error handling, which helps prevent common coding pitfalls. It can be enabled globally or at the function level using the 'use strict' directive, and it introduces various restrictions, such as disallowing implicit global variable declarations and the use of certain keywords. Overall, strict mode promotes better programming practices and improves code maintainability.

Uploaded by

webcomputer06
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

JavaScript’s Strict Mode and Why You Should

Use It
Posted on http://cjihrig.com/blog/javascripts-strict-mode-and-why-you-should-use-it/
by Colin Ihrig.
Starting with ECMAScript 5, developers are able to place their code into a more constrained form
of execution known as strict mode. Strict mode improves JavaScript code by enforcing better
programming practices and eliminating some of the language’s insecure and ill-advised features.
Strict mode is enabled by adding the following directive to your code:
"use strict";

The “use strict”; directive can be used in two ways. The first method of invoking strict mode is at
the file level. By adding the directive at the beginning of a file (the directive may only be preceded
by comments and whitespace), strict mode is enabled in a global context. This means that all of
your code will be evaluated in strict mode. Caution must be taken when concatenating strict and
non-strict scripts together. Placing a strict script first will force the non-strict script to be evaluated
in strict mode. Placing a non-strict script first will cause the opposite behavior. This caused some
problems for Amazon.
The second way to enable strict mode is at the function level. To enable this level of strict mode,
place the “use strict”; directive at the beginning of the function body. As with global strict mode,
the directive may only be preceded by whitespace and comments. Using strict mode at the function
level allows a programmer to mix and match strict and non-strict functions in the same file. This is
useful when some legacy code relies on features that have been deprecated in strict mode. The
following example shows how strict and non-strict functions can coexist in a single file.
function foo() {
"use strict";
// this function is executed in strict mode
}

function bar() {
// this function is executed in non-strict mode
}

One of the nice things about strict mode is its backward compatibility. Older versions of JavaScript
will treat the “use strict”; directive as a meaningless string literal and ignore it. However, newer
versions of JavaScript will give the statement special treatment and switch to strict mode. For
browsers that support strict mode, the following restrictions apply.

Implicit Global Variable Declaration


JavaScript has an interesting way of handling variable declarations. Variables that are not declared
using the var keyword are implied to be global variables. The following piece of code uses three
variables – ‘x’, ‘y’, and ‘z’.
function foo() {
var x;
var z;

x = 1;
y = 2;
z = x + y;
}

Notice that only the variables ‘x’ and ‘z’ are declared using the var keyword. There is a good
chance that the programmer also meant to declare ‘y’, but mistakenly did not. The code will
execute properly, but with the side effect of creating a global variable named ‘y’ with the value 2.
Since window is the global object, this is equivalent to writing:
window.y = 2;

This behavior can be problematic if ‘y’ is already defined elsewhere and is expected to have a
different value. This leads to code that doesn’t scale well and is difficult to debug. Enabling strict
mode will catch this problem. Instead of making ‘y’ a global variable, an exception will occur. The
exception shown in Chrome looks like this:
ReferenceError: y is not defined

The with Statement


The with statement provides a shorthand notation for working with an object’s properties. Inside a
with statement, it can be difficult to tell if a variable belongs to the object in question or some other
scope. The following code uses a with statement to output the document’s title. There is also a
local variable named ‘title’, which is ignored inside the with statement. In a more complex piece of
code, a programmer could easily introduce bugs related to variable scoping when using with
statements.
function foo() {
var title = "Not the page title";
with (document) {
write(title + "<br />");
write("contains a with statement");
}
}

In strict mode, the with statement has been completely disabled. Any attempt to use the with
statement will result in the following syntax error. Note: A much better idea is to assign the object
to a variable and access it’s properties via the variable.
SyntaxError: Strict mode code may not include a with statement

Identifier Naming
Strict mode places several naming restrictions on variables, functions, and parameters. The strings
‘eval’ and ‘arguments’ cannot be used as identifiers, nor can they have values assigned to them.
Because JavaScript has a built-in ‘eval’ function and ‘arguments’ object, this eliminates possible
confusion. Attempting to use ‘eval’ or ‘arguments’ as a name results in the following exception:
SyntaxError: Variable name may not be eval or arguments in strict mode

Additionally, identifiers can no longer use any of the following future reserved keywords:
• implements
• interface
• let
• package
• private
• protected
• public
• static
• yield

this Usage
Use of a ‘this’ variable is common in object-oriented programming. Inside a function, the ‘this’
variable points to the object that owns the function. However, when a function does not belong to
any specific object, the ‘this’ variable points to the global object (window). Strict mode removes
accidental or malicious access of the global object by assigning ‘this’ a value of undefined. If a
function is owned by an object, then ‘this’ still points to that object as expected. In the following
example, the function ‘foo’ returns undefined.
function foo() {
"use strict";
return this;
}

Read-only Properties
JavaScript allows developers to create read-only properties on objects. Attempts to write a new
value to a read-only property fail silently in non-strict code. In other words, the property’s value
remains unchanged, but the program does not provide any warning/error. In strict mode, such
behavior will cause the script to throw an exception. The following example creates a read-only
property named ‘prop1′. In strict mode, the subsequent assignment of ‘prop1′ causes a TypeError
exception.
function foo() {
"use strict";
var obj = Object.defineProperties({}, {
prop1 : {
value : 1,
writable : false
}
});

obj.prop1 = 2;
}

Non-extensible Objects and Variables


In JavaScript, adding new properties to an object is trivial – just assign a value to it. JavaScript also
provides a mechanism for preventing the addition of new properties. By setting an object’s internal
‘extensible’ attribute to false, the addition of new properties to an object will fail silently. Once
again, strict mode changes silent failure to a TypeError exception. The following code attempts to
add a new property to a non-extensible object.
function foo() {
"use strict";
var obj = {prop1 : 1};

Object.preventExtensions(obj);
obj.prop2 = 2;
}

The object ‘obj’ is constructed with a single property, ‘prop1.’ When ‘Object.preventExtensions’ is
called, ‘obj’ becomes non-extensible. The attempt to add ‘prop2′ to the object results in the
following exception:
TypeError: Can't add property prop2, object is not extensible

Duplicate Parameters and Properties


Non-strict JavaScript allows objects to contain multiple properties with the same name. When the
same name is used multiple times, only the last declaration is used. Strict mode requires that all
property names are unique. In the following example, the object ‘obj’ contains two properties
named ‘prop1′. In non-strict mode, the value of ‘prop1′ would be 3. However, when strict mode is
enabled a syntax error occurs.
// while in strict mode
obj = {
prop1 : 1,
prop2 : 2,
prop1 : 3
};

Similarly, non-strict functions may have multiple parameters with the same name. In strict mode,
this is not allowed. In the following example, duplicating ‘param1′ causes a syntax error.
function foo(param1, param1) {
"use strict";
alert(param1);
}

eval Variables
Non-strict code can use the ‘eval’ function to add new variables to the surrounding scope. Prior to
native JSON support in browsers, ‘eval’ was commonly (and unsafely) used to construct objects
from strings. The constructed objects then became a part of the surrounding scope. In strict mode,
‘eval’ cannot introduce new variables. When executed in strict mode, the following piece of code
will not introduce the ‘bar’ variable into the surrounding scope. Note: if a function containing
‘eval’ is executed in strict mode, then the code inside the ‘eval’ function is also executed in strict
mode.
// while in strict mode
eval("var bar = 10;");

The delete Operator


The delete operator is used to remove properties from objects. However, some properties cannot be
deleted. Non-configurable properties are of the variety that cannot be deleted. Non-strict code will
fail silently when an attempt is made to delete a non-configurable property. Such an attempt throws
a TypeError exception when executing in strict mode. In the following example, the object ‘obj’ has
a non-configurable property named ‘prop1′ and a configurable property named ‘prop2′. Since
‘prop2′ is configurable, it is perfectly acceptable to delete it. An exception is not thrown until the
attempt to delete ‘prop1′ is made.
function foo() {
"use strict";
var obj = Object.defineProperties({}, {
prop1 : {
value : 1,
configurable : false
},
prop2 : {
value : 2,
configurable : true
}
});

delete obj.prop2;
delete obj.prop1;
}

The delete operator is intended to work on object properties. Attempting to delete normal variables
and functions will result in a syntax error. All of the delete operations in the following example will
fail.
function foo(param1) {
"use strict";
var bar = 1;
function baz() {};

delete param1;
delete bar;
delete baz;
}

Using arguments, caller, and callee


When a function is called, a special object named ‘arguments’ is created in the function’s scope.
’arguments’ is an array-like object that contains the arguments passed to the function. In the
following example ‘arguments[0]‘ and ‘arg1′ hold the same value, as do ‘arguments[1]‘ and ‘arg2′.
In non-strict mode, updating one value automatically updates the value it maps to. At the end of
‘bar’, the values of ‘arg1′ and ‘arg2′ have been swapped even though values were only assigned to
the ‘arguments’ array. In strict mode, the aliased values are not automatically updated. Therefore,
when run in strict mode, the values of ‘arg1′ and ‘arg2′ are unchanged at the end of ‘bar’.
function foo() {
bar(1, 2);
}

function bar(arg1, arg2) {


var temp = arguments[0];
arguments[0] = arg2;
arguments[1] = temp;
alert(arg1 + " " + arg2);
}

The ‘arguments’ object also contains a pointer to the function that is currently executing. The
current function is referred to as the callee, and can be referenced using ‘arguments.callee’. This
syntax is only useful inside an anonymous function, because anonymous functions do not have
names. In any other case, it makes more sense to refer to the callee by name. In strict mode, access
to ‘arguments.callee’ is not allowed.
A similar method can be used to determine where a function call was made from. An
‘arguments.caller’ object was available in older browsers, but has since been deprecated. However,
the calling method can still be determined using ‘arguments.callee.caller’. Strict mode also
prohibits access to the caller. In the following example, ‘bar’ is not in strict mode. However,
attempting to access ‘arguments.callee.caller’ will still fail because ‘foo’ is a strict mode function.
function foo() {
"use strict";
bar(1, 2);
}

function bar(arg1, arg2) {


var caller = arguments.callee.caller
}

UPDATE (11/21/14)
Enabling strict mode allows some JavaScript engines, such as v8, to optimize code that it otherwise
would not. In non-strict mode, referencing ‘arguments’ and a named argument in the same function
will cause v8 to not optimize the function. For a slightly more detailed read, see this issue and my
personal will-it-optimize project.

UPDATE (11/21/14)
I’d also like to thank Chris Dickinson for providing an excellent example of (what I feel are) bad
coding practices that strict mode prevents. The following example returns 102 in non-strict mode,
but throws an error in strict mode as one function tries to overwrite the arguments of another
function.
// "use strict"; // uncomment this line to see an error thrown
function modify() {
poison.arguments[0] = 100;
}

function poison(a, b) {
modify();
return a + b;
}

console.log(poison(1, 2));

Octals
Octal variables represent numbers in the base-8 number system. They are rarely used and have a
very confusing syntax. Positive octal numbers are prefixed with a ’0′ while negative octals begin
with ‘-0′. For example, declaring the octal number 100 looks like this:
var foo = 0100;

Since people tend to ignore leading zeros, this can easily be confused with the decimal value 100.
However, a quick call to ‘parseInt()’ shows that the octal value is actually equal to 64 when
converted to decimal. To resolve this problem, strict mode disallows the use of octals. Octal
variables and octal escape sequences are both treated as syntax errors in strict mode.

You might also like