In this post, we are going to cover the basics of strict mode and cover the most important features of it. Here and there, I might recommend some additional readings to ease your understanding of strict mode.
In order to enable a strict mode in your script, you simply need to add “use strict” at the very first line of your script.
On the other hand, strict mode and sloppy mode can coexist. You can use both in the same file.
To use both strict and sloppy modes, you need to write the code that you want in strict mode after the “use strict” while the rest before the “use strict”.
Additionally, you can use strict mode inside the function body which is often mentioned as function-level strict mode.
On the other hand, you cannot use strict mode inside the function if it is using default parameters, rest, or restructuring.
Default parameters example
Rest parameters example
Destructured parameters example
There are various situations when strict mode is enabled automatically and you don’t need to enable it yourself.
Strict mode is automatically applied in:
In all parts of the class, strict mode is enabled automatically.
JSON is a data format often used to transmit data between servers and web applications. It always works in a strict mode and you cannot turn it off.
In strict mode, you cannot re-declare a variable without using var, let, or const. This feature prevents us from creating global variables.
If you are not familiar with variables, I recommend you read my post about variables.
There are 3 situations where you cannot assign property in strict mode.
In Objects, properties have their attributes, one of which is writable. Writable defines whether the value can be changed.
When in a sloppy mode, if you try to assign a new value even if the writable is false, it’s not going to throw any error. It will not rewrite the value but the error will remain “silent”.
In the strict mode, however, you are going to receive an error and won’t reach the console.log line.
In objects, we have a special method that starts with a getter which retrieves a property value, and also a setter method that sets/modifies a property.
A getter-only property means that it provides only a way to get the value. Getter-only properties automatically become read-only.
Read-only means that the object property attribute writable is set to false - it cannot be modified.
In a sloppy mode, we will have a similar situation to the above example. There will be no errors thrown.
While in the strict mode, we will receive an error.
In this example, we aren’t going to receive any errors. But let’s enable strict mode.
And that is when we receive an error.
Object properties that have an attribute configurable set to false, cannot be deleted. This attribute controls whether an attribute can be deleted. Similar to the examples above, if we try to delete an unconfigurable attribute, it will not delete it but will not throw an error either!
In strict mode, however, we will see an error:
In sloppy mode, if we repeat the parameter names, we will not see any error again!
It might seem so easy but when you have many parameters or more complex code, you might miss this error.
If we use it in a sloppy mode we will be able to declare a variable with var in string.
In a strict mode, however, it’s not allowed:
Besides restricted usage of eval strings, we also cannot assign any value to eval as well as arguments object.
Without a strict mode, it will work perfectly:
In a strict mode, it will not reach the console.log:
If you are not sure what arguments are, I recommend you to read about the arguments object section in a post about objects.
Primitive values are data types that represent one value — undefined, null, boolean, string, number, and symbol.
If you try to do so anyway, in a sloppy mode it won’t warn you about anything.
Once we enable strict mode, we will see the error:
Before going further, make sure you get familiar parameters and arguments in my post about functions.
When we don’t use a strict mode, parameters and arguments can lose synchronization and act unexpectedly.
Let’s inspect the example below where we use a sloppy mode:
Take a closer look at each console and guess why we have such results from your own experience.
We have a parameter “a” where we passed an argument 1. In the function body, we try to reassign a value to a parameter with a value of 12.
Next, we also assign a value with the help of arguments object by targeting the value with the index.
In other words, in both cases, we tried to change the value of the “a” parameter — first via the parameter name and then via the arguments object and index. As a result, we get the value 13 everywhere as it was the last value we assigned.
Now look at what happens in the strict mode!
What is going on here? We try to do the same but we have some weird results. The attempt to reassign the value to the “a” parameter failed.
Because in a strict mode, the arguments object and parameter do not sync and because variable assignment works differently in this case.
What happened is that the “a” we wrote inside the function body shadowed the parameter and now is acting like a separate variable not connected to the parameter.
But the argument object acts as expected and plays the main role now of controlling the parameter value.
However, when we use a strict mode it becomes undefined which helps to avoid extra errors in later usage of this keyword.
It will return a function reference from where the function was called, in our case, we called the function from the callerFunc:
However, in a strict mode, it’s not possible as such access to the caller might cause vulnerability issues.
Here is what happens in a strict mode:
We also have another property called callee. This property used to be useful for recursive functions when a function needed to access/refer to itself. A recursive function is a function that calls itself until meets specific criteria.
Here is an example of a recursive function with a callee property that calls itself until it reaches one and returns the sum of each number from 1 to the number we passed to it:
We can no longer do this in a strict mode:
For example, you cannot create variables with names like const, try, this, true, and so on.
Strict mode adds even more reserved words:
Do we really need a strict mode or it’s an extra layer of complexity?
I believe that these days everyone should be using a strict mode. Even if you are a senior and have years of experience, we all are human and might make mistakes. A strict mode is a helping hand in avoiding some errors. Its features help to identify issues at the very start of the project instead of piling up many problems at the later stage.
It prevents unintentional global variable creation, doesn’t silence the errors, and shows us right away where we need to make corrections exactly.
It also helps to control the this keyword and doesn’t refer it to the global object.
Even though it’s not very easy to adjust an old codebase when switching to a structure mode, it’s still a huge step toward cleaner and safer code.