You might be familiar with seeing the following directive at the top of JavaScript files.
'use strict';
// or
"use strict";
But you might not be fully aware as to what exactly it's doing internally. In this post, we'll be going deeper into uses and effects of running your code in 'strict' mode. Because it goes beyond just ensuring that you have a proper variable declaration.
Overview
'use strict' was introduced in 2015 in the ECMA2015 update to JavaScript. One of biggest changes that it introduced was the fact that it eliminated many silent errors and instead changed them to actual throwable errors. Technically, this is a good thing, but also could be construed as 'bad' as it might lead to broken unrunnable scripts and functions.
All modern browsers support the use of 'use strict', except for IE9 and below. But because it is essentially just a string literal, all browsers support including it whether it does anything or not.
The main reason for its creation, is basically because JavaScript tends to be very forgiving, which is why many developers choose to use it is their first programming language. You can have all sorts of (technically) errors in your code, but the JavaScript engine will still do its best to figure out what it is that you are trying to say, or some cases not say anything and just not run the code. For example:
var x = 20;
y = 10;
These are both valid statements in JavaScript. Both the x and the y variable will get initialized appropriately in this case. However, since the addition of let and const into the variable declaration syntax things have gotten trickier. For one, not including any declaration JavaScript now has to imply that you meant to define the variable as a var. But it's only a guess. You could have really meant const.
These are the kind of errors that strict mode aims to address.
'use strict';
var x = 20;
y = 10;
Under 'strict mode', the previous would result in the following error.
You explicitly have to declare each and every variable in this mode, which can reduce the possibility of errors in your code in the future. In a general sense, that is what strict mode is. It is a way to address and correct the shortcomings that JavaScript has adopted from its initial days.
Also note, that the 'use strict' directive is only recognized at the beginning of a script or a function!
Here is athorough list of everything else that 'use strict' brings with it and why you should aim to include it moving forward.
Strict functions
If you have a substantial amount of code, then you might not be able to simply use 'strict mode' across your entire codebase. This is why you also have the option of only including it within the scope of single functions.
function func1(){
'use strict';
y = 10; // syntax error
}
y = 10; // allowed
In the above example, only the code within the function body will be run under strict mode. This makes for an ideal way to slowly transition your code, particularly if you have an older codebase.
Also note that functions embedded within a strict function would also inherit these new features.
Strict modules
Modules were introduced to JavaScript in ECMAScript 2015. By default, modules are automatically running under strict mode without any need of a declaration.
function func1(){
y = 10;
}
export default func1;
This makes sense as both features were introduced in the same ES2015 release cycle.
Avoid writing to non-writeable global properties
In the past, attempting to write to a non-writeable property would essentially do nothing. That would look something like the following:
var undefined = 20;
In this case, undefined is a non-writeable global variable. Running this statement in a non-strict mode would result in a silent error. Essentially, there would be no error message and JavaScript would ignore it. But how would a developer know that something has gone awry? They wouldn't.
Under strict mode however, this will throw a TypeError back to the console stating that "undefined" is read-only.
Prevents deleting "undeletable" properties
The following statement could cause some trouble to the average programmer:
delete Object.prototype;
Lucky for us, JavaScript will ignore that statement and continue on its way as if nothing has happened.
Unless you are running under strict mode, in which case that statement would throw a TypeError back as well.
The main difference here is that in the past, you simply would not know that something has gone wrong. Because deleting built-in system wide objects is a good idea never.
Requires function parameter names to be unique
The following is a potentially confusing, yet valid way to set parameters in a given function.
function addNumbers(a, b, b, c, c)
{
}
Duplicating parameter names won't have the effect that most people desire however. In this case, the former duplicate value will override the latter.
The only way to retrieve each individual value in this case, would be to use the arguments property, in which case arguments[0], arguments[1], arguments[2], etc would be valid.
Under strict mode, however, this would throw a syntax error. Which is the more ideal scenario as having duplicate parameter names can lead to confusion, unless there is some specific reason as to why this is the case.
Prevents '0' prefixed octal literals
In non-strict mode, a number beginning with a 0, like 0233 for example, is interpreted as an octal number. In which case the result is 155 in decimal.
This is no longer allowed under strict mode and the following would throw a syntax error.
If you need to create an octal value, it can be done however, using the new prefix 0o.
var num = 0o10; // valid
var num2 = 010; // Syntax error
Again, strict mode still allows for much of the functionality under non-strict mode, it just needs to be more explicitly stated.
Prevents setting properties on primitive values
The following was allowed under a non-strict environment in the past, though it did not run or have any effect on the code. You might be detecting a theme at this point.
false.x = 20;
Under strict mode, this would throw a TypeError. As it should.
Deleting variables or objects
The delete operator in JavaScript can be used to remove properties from a given object.
var car = {
make: 'Honda',
model: 'Civic'
}
delete car.make;
In this particular case above, the make property would no longer be available in the given car object.
In the past, you could technically have the following syntax
var x = 20;
var y = 10;
delete x; // would do nothing
The compiler would again, ignore that particular statement. x would still remain in memory for usage. Under strict mode however, this is no longer allowed and would result in a Syntax Error.
The same goes for attempting to delete objects or functions as well.
Reserved keywords
The following keywords can not be used as variable names under strict mode moving forward.
- implements
- interface
- let
- package
- private
- protected
- public
- static
- yield
Other keywords planned for future implementations and updates in JavaScript will also no longer be allowed as variable names.
Final words
There is a good chance that if strict mode were added to some of the biggest websites in the world, that most of them would have severe issues and would no longer function properly.
And that's because for far too long JavaScript has been a very coder-friendly and browser friendly language. It had to be, otherwise small little glitches in the code would bring down entire pages and thus make the internet unusable.
In the future, strict mode will be the de facto standard more than likely on every browser. But for now, if you can, it's good practice to begin to include it so that older intrinsic bugs are no longer an unexpected issue.