RegExp[Symbol.species]

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

RegExp[Symbol.species] は静的なアクセサープロパティで、特定の RegExp メソッドのコピーされた正規表現を構築するのに使用されたコンストラクターを返します。

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

試してみましょう

class MyRegExp extends RegExp {
  // Overwrite MyRegExp species to the parent RegExp constructor
  static get [Symbol.species]() {
    return RegExp;
  }
}

const regex1 = new MyRegExp("foo", "g");

console.log(regex1.test("football"));
// Expected output: true

構文

js
RegExp[Symbol.species]

返値

get [Symbol.species] が呼び出されたコンストラクター (this) の値。この返値は、コピーした RegExp インスタンスを作成するために使用されます。

解説

[Symbol.species] アクセサープロパティは、 RegExp の既定のコンストラクターを返します。サブクラスのコンストラクターは、オーバーライドすることでコンストラクターの割り当てを変更することができます。既定の実装は基本的に次の通りです。

js
// 説明のための架空の基礎実装
class RegExp {
  static get [Symbol.species]() {
    return this;
  }
}

この多相的な実装により、派生したサブクラスの Symbol.species も既定でコンストラクター自身を返すようになります。

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

一部の RegExp メソッドは、exec() を実行する前に現在の正規表現インスタンスのコピーを作成します。そのため、lastIndex への変更が保持されないような副作用があります。Symbol.species プロパティは、新しいインスタンスのコンストラクターを決定するために使用されます。正規表現インスタンスをコピーするメソッドは以下の通りです。

通常オブジェクトの species

Symbol.species プロパティは、既定のコンストラクターを返します。 RegExp オブジェクトであれば、 RegExp コンストラクターを返します。

js
RegExp[Symbol.species]; // function RegExp()

派生オブジェクトの species

派生クラスのコレクションオブジェクト(たとえば、独自の正規表現を表す MyRegExp)では、 MyRegExp の species は MyRegExp コンストラクターです。しかし、派生クラスのメソッドで親である RegExp オブジェクトを返すようにこれをオーバーライドしたくなるかもしれません。

js
class MyRegExp extends RegExp {
  // MyRegExp の species を親である RegExp コンストラクターにオーバーライドします。
  static get [Symbol.species]() {
    return RegExp;
  }
}

または、これを使用してコピープロセスを監視することができます。

js
class MyRegExp extends RegExp {
  constructor(...args) {
    console.log("Creating a new MyRegExp instance with args:", args);
    super(...args);
  }
  static get [Symbol.species]() {
    console.log("Copying MyRegExp");
    return this;
  }
  exec(value) {
    console.log("Executing with lastIndex:", this.lastIndex);
    return super.exec(value);
  }
}

Array.from("aabbccdd".matchAll(new MyRegExp("[ac]", "g")));
// Creating a new MyRegExp instance with args: [ '[ac]', 'g' ]
// Copying MyRegExp
// Creating a new MyRegExp instance with args: [ MyRegExp /[ac]/g, 'g' ]
// Executing with lastIndex: 0
// Executing with lastIndex: 1
// Executing with lastIndex: 2
// Executing with lastIndex: 5
// Executing with lastIndex: 6

仕様書

Specification
ECMAScript® 2025 Language Specification
# sec-get-regexp-%symbol.species%

ブラウザーの互換性

Report problems with this compatibility data on GitHub
desktopmobileserver
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
Deno
Node.js
[Symbol.species]

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support

関連情報