Get to know MDN better
このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docs コミュニティーについてもっと知り、仲間になるにはこちらから。
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2016年3月.
コンストラクター関数(クラスを含む)または null と評価される式。
extends キーワードは、組み込みオブジェクトと同様にカスタムクラスをサブクラス化するために使用することができます。
new で呼び出すことができ、 prototype プロパティを持つコンストラクターであれば、親クラスの候補になることができます。例えば、バインド済み関数や Proxy は構築可能ですが、これらは prototype プロパティを持たないので、サブクラス化できません。
ParentClassの prototype プロパティは Object または null でなければなりませんが、オブジェクトでない prototype は本来の動作をしないので、実際にはほとんど気にすることはないでしょう。(new 演算子では無視されます。)
extends は ChildClass と ChildClass.prototype の両方のプロトタイプを設定します。
| extends 節がない | Function.prototype | Object.prototype |
| extends null | Function.prototype | null |
| extends ParentClass | ParentClass | ParentClass.prototype |
extends の右辺は識別子である必要はありません。コンストラクターとして評価される式なら何でも使用することができます。これはミックスインを作成するのに有益なことが多いです。 extends 式の this 値はクラス定義の外側の this であり、このクラスは初期化されていないので、クラス名を参照すると ReferenceError になります。この式では await および yield は期待通りに動作します。
基底クラスはコンストラクターから何らかのものを返すことができますが、派生クラスはオブジェクトを返すか undefined を返さなければなりません。
親クラスのコンストラクターがオブジェクトを返す場合、クラスフィールドをさらに初期化するときに、そのオブジェクトが派生クラスの this 値として使用されます。このトリックは「返値の上書き」と呼ばれ、派生クラスのフィールド(プライベートのものを含む)を無関係なオブジェクトに定義することができます。
警告: 標準化委員会は、これまでの仕様にあった組み込みクラスにおけるサブクラス化メカニズムは過剰に設計されており、パフォーマンスとセキュリティへの無視できない影響を発生させているという見解を固めました。新しい組み込みメソッドはサブクラスについてあまり考慮されておらず、エンジンの実装者は一部のサブクラス化メカニズムを除去するかどうか調査しています。組み込みクラスを拡張する際には、継承の代わりにコンポジションを使用することを検討してください。
クラスを拡張する際に期待されることをいくつか示します。
しかし、上記のような期待を適切に実装するには、只ならぬ努力が必要です。
これらの問題は組み込みクラスに固有のものではありません。自分自身で作成したクラスについても、同じような決定をしなければならないことがあるでしょう。しかし、組み込みクラスでは、最適化とセキュリティがより大きな関心事です。新しい組み込みメソッドは常に基底クラスを構築し、可能な限りいくつかのカスタムメソッドを呼び出します。上記の期待値を達成しながら組み込みクラスをサブクラス化したい場合は、既定値の動作が組み込まれているメソッドをすべてオーバーライドする必要があります。既定では継承されているため、基底クラスに新しいメソッドを追加すると、サブクラスの意味づけが崩れる可能性があります。したがって、組み込みクラスを拡張するためのより良い方法は、コンポジション を使用することです。
extends null は、Object.prototype を継承しないオブジェクトを簡単に作成できるようにするために設計されました。しかし、コンストラクター内で super() を呼び出すべきかどうかが未確定なため、オブジェクトを返さないコンストラクターの実装を使用して、実際にそのようなクラスを構築することは可能ではありません。 TC39 委員会はこの機能を再び使えるようにするために作業しています。
代わりに、コンストラクターから明示的にインスタンスを返す必要があります。
最初の例では、 Square と呼ばれるクラスを Polygon と呼ばれるクラスから作成します。この例は、ライブデモ(ソース)から転載しています。
クラスは通常の(構築不可能な)オブジェクトを継承することはできません。このオブジェクトのすべてのプロパティを継承したインスタンスで利用できるようにして、通常のオブジェクトを継承したい場合は、代わりに Object.setPrototypeOf() を使用することができます。
この例では、組み込みの Date オブジェクトを拡張します。この例は、ライブデモ (ソース) から転載しています。
JavaScript のオブジェクトはすべて既定では Object.prototype を継承しているので、一見すると extends Object と書くのは冗長に見えます。 extends をまったく書かない場合と異なる形で言えば、コンストラクター自体が Object.keys() のような静的メソッドを Object から継承していることくらいです。しかし、どの Object の静的メソッドも this の値を使用していないため、これらの静的メソッドを継承することに有益な値はありません。
Object() コンストラクターはサブクラスのシナリオを特殊化します。 super() によって暗黙的に呼び出された場合、常に new.target.prototype をプロトタイプとする新しいオブジェクトを初期化します。 super() に渡す値は無視されます。
この動作を、サブクラスを特殊化しないカスタムラッパーと比較してみてください。
派生配列クラス MyArray で Array オブジェクトを返したい場合もあります。 species パターンを使うと、既定のコンストラクターを上書きすることができます。
例えば、Array.prototype.map() のような既定のコンストラクターを返すメソッドを使用する場合、これらのメソッドは MyArray オブジェクトの代わりに、親の Array オブジェクトを返すようにします。シンボル Symbol.species を使用すると、これを行うことができます。
この動作は、多くの組み込みコピーメソッドで実装されています。この機能の注意点については、組み込みクラスのサブクラス化の説明を参照してください。
抽象サブクラスまたはミックスインは、クラスのテンプレートです。クラスはスーパークラスを 1 つしか持つことができないので、例えばツールクラスからの多重継承は不可能です。機能はスーパークラスが提供しなければなりません。
スーパークラスを入力とし、そのスーパークラスを拡張したサブクラスを出力とする関数が、ミックスインを実装するために使用することができます。
これらのミックスインを使用するクラスは、次のように書くことができます。
オブジェクト指向プログラミングにおいて、継承はとても強い結合関係です。これは基底クラスのすべての振る舞いが既定でサブクラスに継承されることを意味します。例えば、 ReadOnlyMap の実装を考えてみましょう。
Map() コンストラクターはインスタンスの set() メソッドを呼び出すからです。
インスタンスが構築済みかどうかを示すためにプライベートなフラグを使用することで、これを回避することができます。しかし、この設計のより重大な問題は、リスコフの置換原則を破ってしまうことです。これは、サブクラスはスーパークラスと置換可能であるべきだという状態です。もし関数が Map オブジェクトを期待するのであれば、 ReadOnlyMap オブジェクトも使用することができるはずです。
継承はしばしば円-楕円問題を引き起こします。なぜなら、どちらの型も、多くの共通の特徴を共有しているにもかかわらず、他の型の振る舞いを完全に内包していないからです。一般的に、継承を使用するとてもよい理由がない限り、代わりにコンポジションを使用する方がよいでしょう。コンポジションとは、あるクラスが他のクラスのオブジェクトへの参照を持っていて、そのオブジェクトを実装の詳細としてのみ使用していることを意味しています。
この場合、 ReadOnlyMap クラスは Map のサブクラスではありませんが、同じメソッドを実装しています。これはコードの重複を意味しますが、 ReadOnlyMap クラスは Map クラスと強く結びつけられているわけではなく、 Map クラスが変更されても簡単に壊れることはありません。例えば、 Map クラスが set() を呼び出さない新しいユーティリティメソッド(getOrInsert() など)を追加した場合、 ReadOnlyMap クラスは getOrInsert() を上書きするように更新されない限り、読み取り専用になります。さらに、ReadOnlyMap オブジェクトは set メソッドをすべて持たないので、実行時にエラーを発生させるよりも正確です。
| ECMAScript® 2027 Language Specification # sec-class-definitions |
Enable JavaScript to view this browser compatibility table.
This page was last modified on 2025年9月13日 by MDN contributors.
Your blueprint for a better internet.
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998–2026 by individual mozilla.org contributors. Content available under a Creative Commons license.