> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# JavaScript Instanceof

The `instanceof` operator is a binary operator that tests whether an object has the `prototype` property of a constructor function or class in its prototype chain, or if the right-hand operand implements a custom type-checking routine via `Symbol.hasInstance`. It evaluates the relationship by reference and returns a boolean value.

```javascript theme={"dark"}
object instanceof constructor
```

* **`object`**: The value (typically an object instance) to be evaluated.
* **`constructor`**: The object, constructor function, or class against which the evaluation is performed.

## Internal Mechanics

When the expression `A instanceof B` is evaluated, the JavaScript engine executes the internal `InstanceofOperator(A, B)` routine, which proceeds as follows:

1. **Target Type Check**: The engine verifies that `B` is an object. If `B` is a primitive value, it throws a `TypeError`.
2. **`Symbol.hasInstance` Delegation**: The engine checks if `B` exposes a method keyed by the well-known symbol `Symbol.hasInstance`.
   * If present, the engine calls this method with `A` as the argument, coerces the result to a boolean, and returns it.
   * *Note:* All standard functions and classes inherit the built-in `Function.prototype[Symbol.hasInstance]` method. This built-in method is what explicitly invokes the `OrdinaryHasInstance` routine (detailed below) to perform the standard prototype chain traversal.
3. **Callable Check**: If `Symbol.hasInstance` is absent, the engine verifies that `B` is callable (possesses a `[[Call]]` internal method). If `B` is not callable, it throws a `TypeError`.
4. **`OrdinaryHasInstance` Invocation**: If `B` is callable but lacks `Symbol.hasInstance`, the engine directly invokes the `OrdinaryHasInstance(B, A)` routine.

The **`OrdinaryHasInstance(C, O)`** routine performs the actual structural validation and prototype traversal:

1. **Bound Function Unwrapping**: If `C` is a bound function (created via `Function.prototype.bind`), it lacks a `prototype` property. The engine extracts its internal `[[BoundTargetFunction]]` and recursively calls `InstanceofOperator(O, [[BoundTargetFunction]])`. This ensures bound functions are evaluated against their original target function's prototype.
2. **Primitive Operand Check**: The engine checks the type of `O`. If `O` is not an object (i.e., it is a primitive), the routine immediately returns `false`.
3. **Prototype Property Validation**: The engine retrieves the `prototype` property of `C`. If `C.prototype` is not an object (e.g., it is `undefined` on an arrow function, or explicitly set to a primitive), the engine throws a `TypeError`.
4. **Chain Traversal**: The engine retrieves the prototype of `O` using the internal `[[GetPrototypeOf]]` method (conceptually identical to `Object.getPrototypeOf(O)`). It recursively compares each prototype in the chain against `C.prototype` using strict reference equality.
5. **Termination**: If a match is found, it returns `true`. If the traversal reaches the end of the prototype chain (`null`) without a match, it returns `false`.

```javascript theme={"dark"}
function Base() {}
function Derived() {}
Object.setPrototypeOf(Derived.prototype, Base.prototype);

const instance = new Derived();

// true: Object.getPrototypeOf(instance) === Derived.prototype
console.log(instance instanceof Derived); 

// true: Object.getPrototypeOf(Object.getPrototypeOf(instance)) === Base.prototype
console.log(instance instanceof Base); 

// true: Object.prototype is at the top of the prototype chain
console.log(instance instanceof Object); 
```

## Technical Nuances

**Bound Functions**
Because the `OrdinaryHasInstance` routine unwraps bound functions before evaluating the `prototype` property, `instanceof` works seamlessly with them despite the absence of a `prototype` object on the bound function itself.

```javascript theme={"dark"}
function Target() {}
const BoundTarget = Target.bind(null);

const instance = new Target();

// true: BoundTarget is unwrapped to Target before prototype evaluation
console.log(instance instanceof BoundTarget);
```

**Symbol.hasInstance Override**
The default prototype chain traversal behavior can be intercepted and overridden. If an object exposes a custom `Symbol.hasInstance` method, the `instanceof` operator delegates the evaluation entirely to it. This allows non-callable objects to act as the right-hand operand without throwing a `TypeError`.

```javascript theme={"dark"}
const PrimitiveNumber = {
  [Symbol.hasInstance](instance) {
    return typeof instance === 'number';
  }
};

// true: Evaluation is delegated to the custom Symbol.hasInstance method
console.log(42 instanceof PrimitiveNumber); 
```

**Primitive Values**
The `instanceof` operator does not trigger auto-boxing for primitive values. During the `OrdinaryHasInstance` routine, if the left-hand operand is a primitive (string, number, boolean, symbol, bigint, null, or undefined), the operator returns `false`. However, because `Symbol.hasInstance` is evaluated *before* the primitive check, custom implementations can successfully return `true` for primitives.

```javascript theme={"dark"}
"token" instanceof String; // false
new String("token") instanceof String; // true
```

**Invalid Prototype Property**
If the right-hand operand is callable but lacks a valid object as its `prototype` property, the engine throws a `TypeError` during the `OrdinaryHasInstance` routine. This commonly occurs with arrow functions, which do not possess a `prototype` property.

```javascript theme={"dark"}
const ArrowConstructor = () => {};

// TypeError: Function has non-object prototype 'undefined' in instanceof check
console.log({} instanceof ArrowConstructor);
```

**Cross-Realm Execution**
JavaScript environments with multiple realms (such as browser windows or iframes) maintain distinct global execution contexts. Each realm has its own set of built-in constructors and prototypes. Because the default `instanceof` behavior relies on strict reference equality, an object instantiated in Realm A will return `false` when evaluated against the corresponding constructor in Realm B.

```javascript theme={"dark"}
// Assuming `iframeWindow` is a reference to another realm
const iframeArray = new iframeWindow.Array();

// false: iframeArray inherits from iframeWindow.Array.prototype, not the current realm's Array.prototype
console.log(iframeArray instanceof Array); 
```

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor JavaScript Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
