TypedArray[@@species]

TypedArray[@@species] は静的アクセサープロパティで、型付き配列のメソッドの返値を構築するのに使われるコンストラクターを返します。

警告: @@species が存在すると、任意のコードの実行が可能になり、セキュリティ上の脆弱性を生み出す可能性があります。また、特定の最適化も非常に難しくなります。エンジンの実装者はこの機能を削除するかどうか調査しています。可能であれば、この機能に頼ることは避けてください。

構文

js
TypedArray[Symbol.species]

返値

get @@species が呼び出されたコンストラクター (this) の値です。この返値は、新しい型付き配列を生成する型付き配列のメソッドで、返値を構築するために使用されます。

解説

@@species アクセサープロパティは、型付き配列オブジェクトの既定のコンストラクターを返します。サブクラスのコンストラクターは、コンストラクターの割り当てを変更するために、これをオーバーライドできます。

js
// 説明のための仮の基盤実装
class TypedArray {
  static get [Symbol.species]() {
    return this;
  }
}

この多態的な実装のために、派生したサブクラスの @@species も、既定ではコンストラクターそのものを返すことになります。

js
class SubTypedArray extends Int8Array {}
SubTypedArray[Symbol.species] === SubTypedArray; // true

既存の配列を変更せず、新しい配列のインスタンスを返す型付き配列のメソッド(例えば、 filter()map())を呼び出した場合、配列の constructor[@@species] にアクセスすることになります。返されたコンストラクターは、配列の型付き配列メソッドの返値を構築するために使用されます。

しかし、Array[@@species] とは異なり、@@species を使って型付き配列を新しく作成する場合、言語が新しく作成する配列が正しい型付き配列であり、元の配列と同じ種類の内容を持つことを確認するようになっています。例えば、BigInt64Array から Float64Array を作成したり、BigInt の配列から BigInt ではない配列を作成することはできません。この場合、TypeError が発生します。

js
class BadArray extends Int8Array {
  static get [Symbol.species]() {
    return Array;
  }
}
new BadArray(1).map(() => 0); // TypeError: Method %TypedArray%.prototype.map called on incompatible receiver [object Array]

class BadArray2 extends Int8Array {
  static get [Symbol.species]() {
    return BigInt64Array;
  }
}
new BadArray2(1).map(() => 0n); // TypeError: TypedArray.prototype.map constructed typed array of different content type from |this|

メモ: SpiderMonkey と V8 の両方にバグがあり、内容物の型が一致するかどうかが調べられません。2 つ目の例では Safari のみで TypeError が発生します。

普通のオブジェクト

species プロパティは、指定した型付き配列オブジェクトの型付き配列のコンストラクターを、既定のコンストラクター関数として返します。

js
Int8Array[Symbol.species]; // function Int8Array()
Uint8Array[Symbol.species]; // function Uint8Array()
Float32Array[Symbol.species]; // function Float32Array()

派生オブジェクトの species

独自の TypedArray のサブクラス(例えば MyTypedArray)のインスタンスでは、MyTypedArray の species は MyTypedArray コンストラクターとなります。しかし、派生クラスのメソッドで親の型付き配列オブジェクトを返すために、これを上書きしたい場合があります。

js
class MyTypedArray extends Uint8Array {
  // MyTypedArray の species を親である Uint8Array コンストラクターに上書き
  static get [Symbol.species]() {
    return Uint8Array;
  }
}

仕様書

Specification
ECMAScript Language Specification
# sec-get-%typedarray%-@@species

ブラウザーの互換性

BCD tables only load in the browser

関連情報