Exploring Javascript's strict mode
Tags: javascript
Published: 2020-01-15 23:47:08

## 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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export). 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](https://developer.mozilla.org/en-US/docs/Glossary/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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) on it so that no one else can add/change/remove properties on that object. 

```js
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:

```js
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:

```js
function sloppy() {
  myGlobal = 5
}

(function() {
  "use strict";
  sloppy()
})()
```

* The function is in strict mode, but the function invocation is in sloppy mode

```js
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!