# prototype

[JS](/web/js.md) ⟩ [value](/web/js/val.md) ⟩ [object](/web/js/val/obj.md) ⟩ prototype

{% hint style="success" %}
desc
{% endhint %}

{% tabs %}
{% tab title="⭐️ 重點" %}
{% hint style="info" %}

* **objects** have a special **hidden property** <mark style="color:purple;">`[[Prototype]]`</mark> that is either <mark style="color:purple;">`null`</mark> or references **another&#x20;**<mark style="color:orange;">**object**</mark> (other types are ignored).
* **that object** is called a “<mark style="color:purple;">**prototype**</mark>”.
* when we access an object's <mark style="color:orange;">**method**</mark>/<mark style="color:orange;">**property**</mark>, and it’s <mark style="color:red;">**missing**</mark>, JavaScript **automatically** takes it from the <mark style="color:purple;">**prototype**</mark>.
  {% endhint %}

{% hint style="success" %} <mark style="color:purple;">**`__proto__`**</mark>&#x20;

* is a [getter/setter](/web/js/val/class/member/getter-setter.md) for <mark style="color:purple;">\[\[Prototype]]</mark> and resides in <mark style="color:orange;">**Object.prototype**</mark>.
* is considered **outdated**, modern methods are:
  * [Object.create(proto, \[descriptors\])](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create)&#x20;
  * [Object.getPrototypeOf(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf)&#x20;
  * [Object.setPrototypeOf(obj, proto)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf)&#x20;
* to access <mark style="color:purple;">`[[Prototype]]`</mark>(which is hidden and internal).

```javascript
// ⭐️ `__proto__` is a getter & setter for [[Prototype]]
obj.__proto__            // call getter
obj.__proto__ = proto    // call setter
Object.getPrototypeOf(obj)
Object.setPrototypeOf(obj, proto)
```

{% endhint %}

{% hint style="danger" %}
[prototype chain](/web/js/val/obj/proto/chain.md) <mark style="color:red;">**can't go in circles**</mark>.
{% endhint %}
{% endtab %}

{% tab title="🔴 主題" %}

* [IteratorPrototype](/web/js/iteration/iterator/iteratorprototype.md) - prototype of all built-in [iterator](/web/js/iteration/iterator.md)s.
  {% endtab %}

{% tab title="👥 相關" %}

* all <mark style="color:yellow;">**objects**</mark> created by [object literal](/web/js/val/obj/create/obj.md) have the <mark style="color:yellow;">**same**</mark> <mark style="color:purple;">**prototype**</mark> - [**Object.prototype**](/web/js/val/builtin/object/object.prototype.md).
* used in object's prototypal [inheritance](/web/js/val/class/inheritance.md).
* function's [prototype](/web/js/val/func/prototype.md) is used as <mark style="color:orange;">**new**</mark> [Broken mention](broken://pages/c3kdqarPVmCRDuMeH3s5)'s <mark style="color:purple;">\[\[Prototype]]</mark>.
* [super](/web/js/val/class/inheritance/super.md) === [<mark style="color:purple;">**`[[HomeObject]]`**</mark>](/web/js/val/obj/method/home-object.md)<mark style="color:purple;">**`.`**</mark>[<mark style="color:purple;">**`[[Prototype]]`**</mark>](/web/js/val/obj/proto.md)⭐️&#x20;
* <mark style="color:purple;">\[\[Prototype]]</mark> is also cloned by [clone(obj)](/web/appendix/custom/custom-functions/clone-obj.md).
* ["pure" object](/web/js/val/obj/create/object.create/pure-object.md) is an object without <mark style="color:purple;">\[\[Prototype]]</mark> (=== <mark style="color:orange;">**null**</mark>).
  {% endtab %}

{% tab title="💈範例" %}
{% hint style="info" %}
下面的程式碼可以看出幾個特點：

* method (含 getter/setter) 有 <mark style="color:orange;">dynamic</mark> <mark style="color:purple;">**`this`**</mark>，程式碼中的<mark style="color:purple;">**`this`**</mark>指的是誰，要看呼叫者(<mark style="color:yellow;">**caller**</mark>)是誰。

* 如果 method 中<mark style="color:orange;">**參照**</mark>到<mark style="color:purple;">**`this`**</mark>的方法或屬性，這時如果 <mark style="color:yellow;">**caller**</mark> (=<mark style="color:purple;">**`this`**</mark>) <mark style="color:red;">**沒有此方法或屬性**</mark>，那就會<mark style="color:red;">**循著**</mark>**&#x20;**<mark style="color:purple;">**prototype chain**</mark>**&#x20;**<mark style="color:red;">**往上找**</mark>。

* 如果 method 中要<mark style="color:red;">**設定**</mark><mark style="color:purple;">**`this`**</mark>的屬性，這時不管 <mark style="color:yellow;">**caller**</mark> 有沒有此屬性，此屬性<mark style="color:red;">**一定會被設定在**</mark>**&#x20;**<mark style="color:yellow;">**caller**</mark>**&#x20;**<mark style="color:red;">**身上**</mark>，而<mark style="color:red;">**不會**</mark>循著 prototype chain 往上找，這點要特別注意❗️
  {% endhint %}

* [replit](https://replit.com/@pegasusroe/JS-object-method-dynamic-this)

```javascript
const { log } = console;

// ------------------------ user ---------------------------
let user = {
    
    // instance properties
    name   : 'John',
    surname: 'Smith',

    // setter/getter
    set fullName(value) {
	[this.name, this.surname] = value.split(' ');
    },

    get fullName() {
	return `${this.name} ${this.surname}`;
    }
};

// -------------------------- admin -------------------------
let admin = {
    __proto__: user,        // ⭐ admin.__proto__ === user
    isAdmin: true,
};

// ------------------------- test --------------------------
[
    admin.fullName,                    // 📤 get: "John Smith"   (from `admin.__proto__`❗)
    admin.fullName = 'Alice Cooper',   // 🖊️ set: "Alice Cooper" (this === admin❗)
    admin.fullName,                    // 📤 get: "Alice Cooper" (from `admin`❗)
    
    user.fullName,                     // 📤 get: "John Smith"   (from `user`, this === user❗)
    
].forEach(x => log(x));
```

{% endtab %}

{% tab title="📘 手冊" %}

* MDN ⟩ [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) ⟩
  * [Object.getPrototypeOf()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf)
  * [Object.setPrototypeOf()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf)
  * [Object.create()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create)
    {% endtab %}

{% tab title="📗 參考" %}

* [ ] You Don't Know JS: this & Object Prototypes ⟩ [Chapter 5: Prototypes](https://gist.github.com/kad3nce/9674522)
* [ ] JS.info ⟩&#x20;
  * [ ] [Class inheritance](https://javascript.info/class-inheritance)
  * [x] [Prototypal inheritance](https://javascript.info/prototype-inheritance)
  * [x] [F.prototype](https://javascript.info/function-prototype)
  * [x] [Native prototypes](https://javascript.info/native-prototypes) - Object.prototype, Number.prototype, Array.prototype ...
  * [x] [Prototype methods, objects without **\_\_proto\_\_**](https://javascript.info/prototype-methods)
  * [x] [Class extends Object?](https://javascript.info/static-properties-methods#class-extends-object) - 說明 <mark style="color:orange;">class A</mark> 與 <mark style="color:orange;">class A extends Object</mark> 有何不同 ⭐️
    {% 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.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.
