このコンテンツはまだ翻訳されていません。 翻訳に協力してください

組み込みのクラスを拡張する

Array、Mapなどの組み込みのクラスも拡張可能です。

例えば、ここでは PowerArray はネイティブの Array を継承しています:

// 1つメソッドを追加しています(その他のことももちろん可能です)
class PowerArray extends Array {
  isEmpty() {
    return this.length === 0;
  }
}

let arr = new PowerArray(1, 2, 5, 10, 50);
alert(arr.isEmpty()); // false

let filteredArr = arr.filter(item => item >= 10);
alert(filteredArr); // 10, 50
alert(filteredArr.isEmpty()); // false

とても興味深い点に注目してください。filtermap といった組み込みのメソッドは、継承された型と同じ型の新しいオブジェクトを返します。そのようにするために、それらは constructor を当てにしています。

上の例では、

arr.constructor === PowerArray

なので、arr.filter() が呼ばれると、内部的には結果の新しい配列は正確に new PowerArray として作成します。 結果に対してさらに PowerArray が持つメソッドを使用し続けることができるため、これは非常に有用です。

さらに、その振る舞いをカスタマイズすることも可能です。

特別な静的な getter Symbol.species があります。存在する場合、このような場合に使用するコンストラクタを返します。

もし、mapfilter のような組み込みのメソッドが通常の配列を返してほしい場合、次のように Symbol.speciesArray を返すようにします:

class PowerArray extends Array {
  isEmpty() {
    return this.length === 0;
  }

  // 組み込みのメソッドは、これをコンストラクタとして使います
  static get [Symbol.species]() {
    return Array;
  }
}

let arr = new PowerArray(1, 2, 5, 10, 50);
alert(arr.isEmpty()); // false

// filter はコンストラクタとして arr.constructor[Symbol.species] を使って新しい配列を作ります
let filteredArr = arr.filter(item => item >= 10);

// filteredArr は PowerArray ではなく Array です
alert(filteredArr.isEmpty()); // Error: filteredArr.isEmpty is not a function

ご覧の通り、これで .filterArray を返します。そのため、拡張機能はこれ以上渡されません。

組み込みでは、静的の継承はありません

組み込みのオブジェクトは独自の静的メソッドを持っています。例えば Object.keys, Array.isArray などです。

そして、既にそれら拡張するネイティブクラスについて話してきました。: Array.[[Prototype]] = Object.

しかし、静的は例外です。組み込みのクラスはお互いから静的なプロパティを継承しません。

つまり、組み込みのコンストラクタ Array のプロトタイプは Object を指していません。 ArrayDateArray.key あるいは Date.keys を持っていません。これは自然なことのように感じます。

これは、DateObject の構造のイメージです:

DateObject の間に繋がりはないことに注目してください。ObjectDate は両方とも独立して存在します。Date.prototypeObject.prototype を継承していますが、それだけです。

チュートリアルマップ

コメント

コメントをする前に読んでください…
  • 自由に記事への追加や質問を投稿をしたり、それらに回答してください。
  • 数語のコードを挿入するには、<code> タグを使ってください。複数行の場合は <pre> を、10行を超える場合にはサンドボックスを使ってください(plnkr, JSBin, codepen…)。
  • 記事の中で理解できないことがあれば、詳しく説明してください。