# JavaScript Error Handling in Strict Mode vs Sloppy Mode: A Complete Guide

> Learn how JavaScript error handling differs between strict mode and sloppy mode. Discover how strict mode catches more errors, simplifying debugging and improving performance.

- Repository: [Kyle Simpson/You-Dont-Know-JS](https://github.com/getify/You-Dont-Know-JS)
- Tags: deep-dive
- Published: 2026-02-24

---

**JavaScript strict mode converts many silent failures from sloppy mode into explicit thrown errors, enabling earlier bug detection and engine optimizations.**

JavaScript operates in two distinct execution modes: the historic *sloppy* (non-strict) mode and the modern *strict* mode enabled via the `"use strict";` directive. According to the [getify/You-Dont-Know-JS](https://github.com/getify/You-Dont-Know-JS) repository, understanding how error handling differs between these modes is essential for writing predictable, debuggable code. Strict mode fundamentally alters the language's behavior by upgrading silent failures to thrown exceptions and introducing early syntax errors that prevent ambiguous code from executing.

## Early Errors vs Runtime Errors in JavaScript Strict Mode

JavaScript distinguishes between **early errors** (caught during parsing or compilation) and **runtime errors** (thrown during execution). Strict mode significantly expands the category of early errors, preventing code with duplicate parameter names, octal literals, or reserved words from ever running. This allows engines to eliminate ambiguous code paths and apply aggressive optimizations, resulting in faster, more predictable execution.

## Silent Failures That Become Exceptions

In sloppy mode, many operations fail silently without throwing errors. Strict mode converts these silent failures into explicit `TypeError` and `SyntaxError` exceptions, making bugs immediately visible.

### Assignments to Read-Only Properties

According to [`types-grammar/ch2.md`](https://github.com/getify/You-Dont-Know-JS/blob/main/types-grammar/ch2.md), attempting to assign a value to a read-only or non-writable property behaves differently depending on the mode.

In sloppy mode, the assignment fails silently and the expression evaluates to the assigned value, but the property remains unchanged. In strict mode, this throws a **`TypeError`**.

```javascript
"use strict";
const arr = Object.freeze([1, 2, 3]);

// Throws TypeError: Cannot assign to read only property '0'
arr[0] = 99;

```

### Property Creation on Primitives

As documented in [`objects-classes/ch2.md`](https://github.com/getify/You-Dont-Know-JS/blob/main/objects-classes/ch2.md), attempting to create new properties on primitive values behaves differently across modes.

Sloppy mode silently ignores the property creation attempt. Strict mode throws a **`TypeError`** because primitives cannot hold properties.

```javascript
"use strict";
let str = "hello";

// Throws TypeError: Cannot create property 'foo' on string 'hello'
str.foo = "bar";

```

### Deleting Non-Configurable Properties

The [`objects-classes/ch1.md`](https://github.com/getify/You-Dont-Know-JS/blob/main/objects-classes/ch1.md) file explains that the `delete` operator behaves more restrictively in strict mode.

In sloppy mode, deleting a non-configurable property returns `false` but does not throw. In strict mode, this throws a **`TypeError`** (or **`SyntaxError`** in some contexts), preventing accidental deletion of sealed or frozen object properties.

```javascript
"use strict";
const obj = Object.freeze({ a: 1 });

// Throws TypeError: Cannot delete property 'a' of #<Object>
delete obj.a;

```

## Variable and Scope Behavior Changes

Strict mode fundamentally changes how variables are declared and resolved, eliminating implicit globals and preventing common scoping mistakes.

### Undeclared Variables and ReferenceError

According to [`scope-closures/ch2.md`](https://github.com/getify/You-Dont-Know-JS/blob/main/scope-closures/ch2.md), strict mode eliminates the automatic creation of global variables from undeclared assignments.

In sloppy mode, assigning to an undeclared identifier creates a new property on the global object. In strict mode, any reference to an undeclared variable throws a **`ReferenceError`**.

```javascript
"use strict";
function foo() {
  bar = 10;  // ReferenceError: bar is not defined
}
foo();

```

### Duplicate Parameter Names

As noted in [`get-started/ch1.md`](https://github.com/getify/You-Dont-Know-JS/blob/main/get-started/ch1.md), strict mode treats duplicate parameter names as syntax errors.

Sloppy mode allows functions to have multiple parameters with the same name, with later parameters shadowing earlier ones. Strict mode throws an **early `SyntaxError`** at parse time, preventing the function from executing.

```javascript
"use strict";
// SyntaxError: Duplicate parameter name not allowed in this context
function add(a, a) {
  return a + a;
}

```

### Octal Numeric Literals

The [`get-started/ch1.md`](https://github.com/getify/You-Dont-Know-JS/blob/main/get-started/ch1.md) documentation indicates that strict mode removes legacy octal literal syntax.

Sloppy mode interprets numbers with leading zeros as octal (e.g., `010` equals 8). Strict mode treats these as **`SyntaxError`** to prevent confusion with decimal notation.

```javascript
"use strict";
// SyntaxError: Octal literals are not allowed in strict mode
const num = 010;

```

## this Binding and Execution Context

Strict mode changes the default binding of the `this` keyword, eliminating accidental global object pollution.

### Default this in Function Calls

According to [`objects-classes/ch1.md`](https://github.com/getify/You-Dont-Know-JS/blob/main/objects-classes/ch1.md), strict mode prevents the default binding from falling back to the global object.

In sloppy mode, calling a function without context (e.g., `foo()`) binds `this` to the global object (`window` in browsers, `globalThis` in Node.js). In strict mode, `this` remains **`undefined`**, and any attempt to access properties on it throws a **`TypeError`**.

```javascript
function showThis() {
  console.log(this);
}

// Sloppy mode: logs Window/globalThis
showThis();

"use strict";
// Strict mode: logs undefined, and this.property throws TypeError
showThis();

```

### with Statement and eval Restrictions

The [`scope-closures/ch1.md`](https://github.com/getify/You-Dont-Know-JS/blob/main/scope-closures/ch1.md) file explains that strict mode eliminates dynamic scoping mechanisms that complicate optimization.

Sloppy mode permits the `with` statement, which modifies the scope chain at runtime, and allows `eval` to introduce new variables into surrounding scopes. Strict mode throws a **`SyntaxError`** for `with` statements and ensures `eval` runs in its own scope, preventing it from leaking declarations.

```javascript
"use strict";
// SyntaxError: Strict mode code may not include a with statement
with (Math) {
  console.log(PI);
}

```

## Class Constructors and Implicit Strict Mode

As documented in [`objects-classes/ch3.md`](https://github.com/getify/You-Dont-Know-JS/blob/main/objects-classes/ch3.md), ECMAScript 2015 classes are implicitly strict regardless of whether the `"use strict";` directive appears in the source.

This means class constructors and methods always exhibit strict mode error handling. Attempting to call a class constructor without the `new` keyword throws a **`TypeError`**, and all the strict mode restrictions regarding `this` binding, variable declarations, and property assignments apply automatically.

```javascript
class Person {
  constructor(name) {
    this.name = name;
  }
}

// Implicitly strict mode behavior
Person("John");  // TypeError: Class constructor Person cannot be invoked without 'new'

```

## Summary

- **Strict mode** converts silent failures into explicit `TypeError`, `ReferenceError`, and `SyntaxError` exceptions, while **sloppy mode** allows many operations to fail silently.
- **Early errors** in strict mode (duplicate parameters, octal literals, `with` statements) prevent code from executing, whereas sloppy mode permits these potentially hazardous patterns.
- **Variable resolution** changes significantly: strict mode throws `ReferenceError` for undeclared identifiers, while sloppy mode creates implicit global properties.
- **`this` binding** defaults to `undefined` in strict mode functions, preventing accidental global object pollution that occurs in sloppy mode.
- **Classes are implicitly strict**, meaning they automatically enforce all strict mode error handling rules regardless of explicit directives.

## Frequently Asked Questions

### What is the main difference between strict mode and sloppy mode in JavaScript?

The primary difference is that **strict mode treats many silent failures as thrown errors**, while sloppy mode allows these operations to fail silently. For example, assigning to a read-only property throws a `TypeError` in strict mode but is ignored in sloppy mode. Additionally, strict mode introduces **early syntax errors** for patterns like duplicate function parameters and octal literals, preventing the code from running at all.

### Does strict mode improve JavaScript performance?

Yes, strict mode can improve performance because it **enables engine optimizations** that are impossible in sloppy mode. By eliminating dynamic scoping mechanisms like `with` and preventing `eval` from introducing new variables into surrounding scopes, strict mode allows compilers to perform static analysis and optimize variable resolution. The removal of silent failure paths also simplifies the execution model, allowing for more predictable and faster code generation.

### How do I enable strict mode in JavaScript?

You can enable strict mode by adding the directive **`"use strict";`** at the beginning of a script or function. When placed at the top of a file, it applies strict mode to the entire script. When placed as the first statement inside a function, it applies only to that function's scope. Note that ECMAScript 2015 classes are **implicitly strict** regardless of whether the directive is present, as are modules (ES6 modules automatically run in strict mode).

### Are JavaScript classes always in strict mode?

Yes, **JavaScript classes are implicitly strict** according to the ECMAScript specification. Whether you include the `"use strict";` directive or not, class constructors and methods always enforce strict mode semantics. This means attempting to call a class constructor without `new` throws a `TypeError`, `this` inside methods defaults to `undefined` rather than the global object, and all other strict mode error handling rules apply automatically within class bodies.