# prototype chain

[JS](/web/js.md) ⟩ [value](/web/js/val.md) ⟩ [object](broken://pages/c3kdqarPVmCRDuMeH3s5) ⟩ [prototype](/web/js/val/obj/proto.md) ⟩ chain

{% hint style="success" %}
the <mark style="color:yellow;">**linked series**</mark> of [**prototype**](/web/js/val/obj/proto.md) <mark style="color:yellow;">**objects**</mark> of an object is called it's <mark style="color:purple;">**prototype chain**</mark>.
{% endhint %}

{% tabs %}
{% tab title="🗺️" %}
{% hint style="info" %}
從下圖可看出 <mark style="color:orange;">**base class**</mark> 與 <mark style="color:orange;">**derived class**</mark> 的連結(繼承)方式，其實是<mark style="color:red;">**不一樣**</mark>的：

* 身為使用者自創的第一個 class，base class <mark style="color:green;">**A**</mark> 與 <mark style="color:green;">**A.prototype**</mark> 所連接的分別是 <mark style="color:blue;">**Function.prototype**</mark> 與 <mark style="color:red;">**Object.prototype**</mark>。
* derived class <mark style="color:yellow;">**B**</mark> 與 <mark style="color:yellow;">**B.prototype**</mark> 則分別連接 <mark style="color:green;">**A**</mark> 與 <mark style="color:green;">**A.prototype**</mark>。
  {% endhint %}

![class B extends A](/files/bUXLymmeADplEa19ATib)
{% endtab %}

{% tab title="⭐️" %}
{% hint style="danger" %}

* <mark style="color:purple;">**prototype chain**</mark> <mark style="color:red;">**can't go in circles**</mark>.
  {% endhint %}

{% hint style="info" %}
the [**assignment**](/web/js/grammar/op/assign/assignment.md) of a [**property**](/web/js/val/obj/prop.md) ([dot](/web/js/val/obj/prop/access/dot-notation-..md)/[bracket](/web/js/val/obj/prop/access/bracket-notation.md) notation) <mark style="color:red;">**always**</mark> <mark style="color:yellow;">**creates**</mark>**/**<mark style="color:yellow;">**sets a property**</mark> in the <mark style="color:orange;">**original**</mark>**&#x20;**<mark style="color:yellow;">**object**</mark>, it <mark style="color:red;">**never**</mark> <mark style="color:yellow;">**modifies objects**</mark> in the <mark style="color:purple;">**prototype chain**</mark>.
{% endhint %}
{% endtab %}

{% tab title="🔴" %}

* function's [prototype](/web/js/val/func/prototype.md) (property) - new instances' prototype<mark style="color:yellow;">**/**</mark>parent object.
* object's [property](/web/js/val/obj/prop.md) - object's <mark style="color:yellow;">**parent**</mark> in <mark style="color:purple;">**prototype chain**</mark>.
* [printPrototypeChain()](/web/js/val/obj/proto/chain/print.md) - print the prototype chain of an object.
  {% endtab %}

{% tab title="👥" %}

* "obj [<mark style="color:blue;">**instanceof**</mark>](/web/js/grammar/op/relational/instanceof.md) A" checks if `A.prototype` is in the <mark style="color:purple;">**prototype chain**</mark> of `obj`.
* function's [prototype](/web/js/val/func/prototype.md) is used in prototype chain.
* [method](/web/js/val/obj/method.md) uses [\[\[HomeObject\]\]](/web/js/val/obj/method/home-object.md)'s [prototype](/web/js/val/obj/proto.md) to trace [super](/web/js/val/class/inheritance/super.md).
* [extending built-in classes](/web/js/val/obj/extend/builtin.md)
* [extending objects](/web/js/val/obj/extend.md)
  {% endtab %}

{% tab title="💈" %}

* replit ⟩ [class B extends A](https://replit.com/@pegasusroe/JS-class-B-extends-A)&#x20;

```javascript
const { log } = console;

// ---------------------- main ------------------------------------

class A {}
class B extends A {};

let a = new A();
let b = new B();

// b's prototype chain
const b1 = b.__proto__;        // B.prototype
const b2 = b1.__proto__;       // A.prototype
const b3 = b2.__proto__;       // Object.prototype
const b4 = b3.__proto__;       // null

// B's prototype chain
const B1 = B.__proto__;
const B2 = B1.__proto__;
const B3 = B2.__proto__;
const B4 = B3.__proto__;

// ---------------------- console ----------------------------------
[
    // b's prototype chain
    b1 === B.prototype,        // true: b is a `B`
    b2 === A.prototype,        // true
    b3 === Object.prototype,   // true
    b4 === null,               // true
    
    B1 === A,                   // true: B inherits from A
    B2 === Function.prototype,  // true: A is a `function`.
    B3 === Object.prototype,    // true: `Function.prototype` is an `Object`.
    B4 === null,                // true: `Object.prototype` inherits from nothing.
    
].forEach(x => log(x));
```

{% endtab %}

{% tab title="📗" %}

* [ ] [JavaScript: The Definitive Guide](/web/master/ref/javascript-the-definitive-guide.md) ⟩ 6.2.3 Prototypes&#x20;
  {% endtab %}

{% tab title="🛠" %}

* [ObjectPlayground](http://www.objectplayground.com/) - visualize prototype chain (cool ⭐️)
  {% endtab %}

{% tab title="🗣" %}

* [A function to print prototype chain for a given object](https://stackoverflow.com/questions/22168033/a-function-to-print-prototype-chain-for-a-given-object)
  {% endtab %}
  {% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lochiwei.gitbook.io/web/js/val/obj/proto/chain.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
