Exploring Javascript's strict mode
Anthony Frehner
Posted on January 15, 2020
Why are we talking about "use strict";
?
It's the year 2020 and you really don't have to think about it 99% of the time - "use strict";
is pretty much a forgotten piece of javascript history.
For example, ESModules are always and forever in strict mode. Bundlers and transpilers like Webpack, Babel, and Rollup automatically insert it into your scripts.
Now that I'm thinking about it, perhaps writing "use strict";
is the "you're not a true web developer unless you know how to insert CSS into HTML" of 2020. :P
So when could you run into strict mode issues?
I recently started trying to debug a nasty Javascript architecture issue with SystemJS and RxJS. In trying to reduce the error down to its simplest form, I was working in a bare HTML file and just using <script>
tags to debug and iterate quickly.
Can you see where this is going?
Because I wasn't using a bundler or ESModules, and because my scripts were running in "sloppy mode", I came across some issues that would have easily been caught had I been running in strict mode.
Strict mode quiz time: frozen objects
Let's say I have an object, and then I use Object.freeze on it so that no one else can add/change/remove properties on that object.
let myObj = {
prop1: "value1"
}
Object.freeze(myObj)
If I were to now try and change myObj.prop1 = "new value"
, what will happen?
...
The answer? Depends on whether you're in strict mode. To clarify: it depends on whether the new assignment is executed in strict mode, and not whether the freeze happened in strict mode.
If myObj.prop1 = "new value"
happens in strict mode, there will be an error thrown. If it happens in sloppy mode, then it fails silently!
Here's an example you can copy/paste into your console and try out:
var frozenObj
function createFrozenObj() {
"use strict";
frozenObj = {
something: "something"
};
Object.freeze(frozenObj);
}
function testStrictInvocation() {
"use strict";
frozenObj.testingStrict = "strict"
}
function testNonStrict() {
frozenObj.notStrict = "not strict"
}
createFrozenObj()
testNonStrict()
testStrictInvocation() // toggle this line to not receive errors
console.log(frozenObj)
Note that no matter if the object was frozen in strict mode, it only matters when the mutation attempts to happen which determines if you get an error or just a silent failure.
What about functions?
In strict mode, trying to do something like test = 5
throws an error saying that you can't make an assignment to an undeclared variable; in sloppy mode, it just fails silently.
So what happens if we try to do that inside of a function in the following situations: will it fail silently or throw an error?
- The function is in sloppy mode, but where the function was invoked is in strict mode. For example:
function sloppy() {
myGlobal = 5
}
(function() {
"use strict";
sloppy()
})()
- The function is in strict mode, but the function invocation is in sloppy mode
function strict() {
"use strict";
myGlobal = 5
}
(function() {
strict()
})()
(And there's no need to test if both functions are in sloppy or strict mode; they behave as expected)
From my testing, it appears that it still follows the same rule that we established above - that errors are thrown only when the actual line of code that is executed is itself in strict mode.
In other words, the first example fails silently because the function sloppy
never sets strict mode, even though it appears to be executed in a context that is in strict mode.
The second example throws an error because it is directly in a strict mode function.
So why does this matter? In the rare situation that you are 1) writing a library, and 2) decide to turn off strict mode for your library, you could (very unlikely but still) potentially be writing a bug that is silently swallowed, even if your users are in strict mode.
So... now what?
I'm not really sure, to be honest. I thought this was just an interesting exercise in exploring something that we developers hardly ever run into, but may come in handy at some undisclosed future date.
If you have other interesting strict mode examples or experiments, let me know!
Posted on January 15, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 29, 2024