> For the complete documentation index, see [llms.txt](https://lochiwei.gitbook.io/web/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lochiwei.gitbook.io/web/js/val/obj/extend/builtin.md).

# extending built-in classes

{% hint style="danger" %}
☢️ <mark style="color:yellow;">**Alert**</mark>❗

<mark style="color:yellow;">**Normally**</mark>, when one class extends another, both <mark style="color:yellow;">**static**</mark> and <mark style="color:yellow;">**non-static**</mark> methods are **inherited**. ( 👉 JS.info ⟩ [Static properties and methods](https://javascript.info/static-properties-methods#statics-and-inheritance) )

But <mark style="color:red;">**built-in classes**</mark> are an <mark style="color:red;">**exception**</mark>. They <mark style="color:red;">**don’t inherit statics**</mark> <mark style="color:yellow;">**from each other**</mark>.❗️❗️❗️
{% endhint %}

{% tabs %}
{% tab title="⭐️ 重點" %}
{% hint style="warning" %}
比較 <mark style="color:blue;">`class B extends A`</mark> 與 Date extends Object 的不同：

* 一般的 class A, B，它們之間<mark style="color:yellow;">**有**</mark> [prototype](/web/js/val/obj/proto.md) 的連結，所以 A 所有的 static properties B 也都有。
* 但 Date 與 Object 之間並<mark style="color:red;">**沒有連結**</mark>，因此雖然有 <mark style="color:blue;">`Object.keys()`</mark> 方法，但卻沒有 <mark style="color:orange;">`Date.keys()`</mark> 方法❗️&#x20;
  {% 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="💈範例" %}

* [replit](https://replit.com/@pegasusroe/extending-Array-1#index.js)

```javascript
// ⭐ extending Array
class PowerArray extends Array {
    // arr.isEmpty
    get isEmpty() { return this.length === 0 }
    // arr.last
    get last() { return this[this.length - 1] }
}

let arr = new PowerArray(1, 2, 5, 10, 50);
let filtered = arr.filter(x => x >= 10);    // ⭐ return `PowerArray`❗

arr.isEmpty,             // false
arr.last,                // 50
Array.isArray(arr),      // true
filtered,                // PowerArray(2) [ 10, 50 ] ⭐
filtered.isEmpty,        // false

PowerArray.__proto__,         // Array
PowerArray.isArray(filtered), // true (⭐ static methods inherited❗)
```

{% endtab %}

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

* [ ] JS.info ⟩ [Extending built-in classes](https://javascript.info/extend-natives)
  {% endtab %}

{% tab title="Untitled" %}

* [Array() constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Array)
  {% endtab %}

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

* [prototype chain](/web/js/val/obj/proto/chain.md)
* [extending objects](/web/js/val/obj/extend.md)
  {% endtab %}
  {% endtabs %}
