Strict Mode in JavaScript
Tags: javascript
Published: 2020-06-28 15:33:29

* [Why was strict mode introduced?](#section-1)
* [What is strict mode in JS?](#section-2)
* [How to enable strict mode?](#section-3)
* [What are the changes in strict mode?](#section-4)

The spec for [ECMAScript 2020](https://www.ecma-international.org/ecma-262/11.0/#sec-strict-variant-of-ecmascript) says:
> The strict variant of the language excludes some specific syntactic and semantic features of the regular ECMAScript language and modifies the detailed semantics of some features. The strict variant also specifies additional error conditions that must be reported by throwing error exceptions in situations that are not specified as errors by the non-strict form of the language.

### Why was strict mode introduced? <a name="section-1" />
Strict mode was introduced in ECMAScript 5 (ES5).
When JS was released, there were a few mistakes or imperfect decisions which got stuck in the language forever. To fix these decisions would mean that all the programs written before the fix would break. To make sure that didn't happen and to make the fixes too, ES5 contributors came up with a workaround where the fixes would be processed only if strict mode is enabled.

### What is strict mode in JS? <a name="section-2" />
Strict mode is an opt-in feature in JS which needs to be explicitly enabled. Once enabled the processing of code changes in a couple of ways:
- Some JS silent errors are changed to throw error exceptions.
- Prohibits use of certain syntax.
- Allows JS engines to perform a few optimisations to evaluate JS code.

### How to enable strict mode? <a name="section-3" />
To enable strict mode `"use strict;"` must be placed at the top of the script. It can only be preceded by comments.
When I say it must be placed at the top of the script, it means at the top of the execution context.

- It can be placed at the top of a `.js` file and the whole file will be processed in strict mode.
```js
// comments...
"use strict";

// code here will be processed in strict mode
...
```

- It can also be placed at the beginning of a function and only the code inside that function would be processed in strict mode. This comes in handy when migration of legacy codebase to strict mode can be made in small individual function-by-function pieces.
```js
// code here will be processed in non-strict mode
var a = "non-strict code";

function strictModeCode(){
  // comments
  "use strict";
  
  // code here will be processed in non-strict mode
  var b = "strict mode"
}
...
```

- JS Modules which was introduced in ES6 has strict mode enabled by default in exported modules.
```js
function moduleFunction() {
  // because this is a module, code here is processed in 
  // strict mode by default
}
export default moduleFunction;
...
```

- All the code inside classes are processed in strict mode by default.
```js
class stictClass {
  // because this is inside a class, code here is processed 
  // in strict mode by default
  constructor() { ... }
}
```

Most of the times the code that we write is transpiled before it is run on production. Most Transpilers enable strict mode by default.

### What are the changes in strict mode? <a name="section-4" />
These are the restriction and exceptions in strict mode in [ECMAScript 2020](https://www.ecma-international.org/ecma-262/11.0/#sec-strict-mode-of-ecmascript):

- `implements`, `interface`, `let`, `package`, `private`, `protected`, `public`, `static`, and `yield` are reserved keywords.

- Assigning values to undeclared variables will throw `ReferenceError` and assigning values to non-writable properties will throw `TypeError`.
```js
a = "undeclared variable"; // ReferenceError
var NaN = "Read Only property" // TypeError

```

- Using `delete` operator on a variable, function argument, or function name will throw a `SyntaxError`. When `delete` is used on non-configurable properties `TypeError` is thrown.
```js
var a = "cool varaible";
delete a; // SyntaxError
delete Object.prototype; // TypeError
```

- Multiple parameters with same name cannot be used in a  function, generator, or asyncFunction.
```js
function duplicateParamNames(a, a) { ... } // SyntaxError
```

- `eval` or `arguments` cannot be used as parameter names for `catch()` statements.
```js
function InvalidParamNames(eval, arguments) { ... } // SyntaxError
```

- `with()` statements are not allowed.
```js
with (expression) { ... } // SyntaxError
```

- If the value of `this` is `undefined` or `null` it is not converted to the global object.

- `this` is not coerced to an object. Boxing does not happen on the value of `this`.

- `eval` or `arguments` cannot be used as a variable names.
```js
var eval = "variable name is eval" // SyntaxError
var arguments = "variable name is arguments" // SyntaxError
```

- Octal numeric literals and octal escape characters are not allowed.
```js
var variableWithOctalLiteralAsValue = 010 // SyntaxError
var variableWithOctalEscapeCharacter = "\010"; // SyntaxError
```

- Functions processed in strict mode define non-configurable properties `callee` and `caller` to it's `arguments` object. These properties are not accessible.
```js
function CalleeAccessor() {
  return arguments.callee; // TypeError
}

function CallerAccessor() {
  return arguments.caller; // TypeError
}
```

- Variables created inside `eval` code will be created in a separate execution context and the `eval` code cannot instantiate variables or functions in the execution context of where eval was called.

- Inside a function if the value of an argument is changed it does not automatically change the associated property in `arguments` object.
```js
function changeArgValue(a) {
  a = 50;
  return [a,arguments[0]];
}
var values = changeArgValue(49);
console.log(values[0]); // 50
console.log(values[1]); // 49
```

- The properties `caller` and `arguments` inside a function cannot be changed or read.
```js
function restrictedPropertiesAccessor(a) {
  changeArgValue.arguments; // TypeError
  changeArgValue.caller; // TypeError
}
```

I have tried to cover all the changes in strict mode. If I have missed something please let me know. :)

Fin.

-------------------------------------------------------------

Next post is going to be about Errors in javascript.

I have taken up a challenge to post good-to-know stuff in JS for thirty days. Please follow me [@zlfnhmd](https://twitter.com/zlfnhmd) for updates and to show some love❤️❤️❤️