# prototype chain

[JS](../../..) ⟩ [value](../..) ⟩ [object](broken-reference) ⟩ [prototype]() ⟩ chain

{% hint style="success" %}
the <mark style="color:yellow;">**linked series**</mark> of [**prototype**]() <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](https://2527454625-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MfvEFZnSBhKT6fJmus0%2Fuploads%2FHJM7omWQTKfkuW7WLO59%2Fprototype%20chain%203.png?alt=media\&token=9c375913-41a0-443b-8f90-8d02c24d7c94)
{% 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**](../../../grammar/op/assign/assignment) of a [**property**](../prop) ([dot](../prop/access/dot-notation-.)/[bracket](../prop/access/bracket-notation) 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](../../func/prototype "mention") (property) - new instances' prototype<mark style="color:yellow;">**/**</mark>parent object.
* object's [prop](../prop "mention") - object's <mark style="color:yellow;">**parent**</mark> in <mark style="color:purple;">**prototype chain**</mark>.
* [print](chain/print "mention") - print the prototype chain of an object.
{% endtab %}

{% tab title="👥" %}
* "obj [<mark style="color:blue;">**instanceof**</mark>](../../../grammar/op/relational/instanceof) A" checks if `A.prototype` is in the <mark style="color:purple;">**prototype chain**</mark> of `obj`.
* function's [prototype](../../func/prototype "mention") is used in prototype chain.
* [method](../method "mention") uses [home-object](../method/home-object "mention")'s [](<> "mention") to trace [super](../../class/inheritance/super "mention").
* [builtin](../extend/builtin "mention")
* [extend](../extend "mention")
{% 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](../../../../master/ref/javascript-the-definitive-guide "mention") ⟩ 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 %}
