@@speciesが実装された
概要
クラスの種族を設定するためのビルトインシンボルが実装された。
解説
例えば、ArrayのサブクラスであるMyArrayを定義し、そのインスタンスmyaryを作ったとき、
myary.map()はArrayではなくMyArrayのインスタンスを返して欲しいと通常思うだろう。
そうしたケースに応えるため、幾つかのビルトインメソッドはconstructorの@@speciesプロパティを見ることで
インスタンスの種族コンストラクタを知り、それを使うようになっている。
とは言え、ビルトインコンストラクタに定義されている@@speciesゲッタはサブクラスを返す挙動をするため、
殆どの場合ではわざわざ自前サブクラスに@@speciesを定義しないで、スーパークラス側のそれを使わせればよい。
もしmyary.map()の結果がMyArrayではないものであって欲しいと思う場合には、定義することでそれを実現させることができる。
例
@@species無し:
class MyArray1 extends Array { clear() { this.length = 0 } } let a1 = new MyArray1(1, 2, 3) a1 = a1.map( v => v + 1 ) // [2, 3, 4] /*map内部の処理 a1はArrayのサブクラスのため、 a1.constructor[@@species] → MyArray1[@@species] → MyArray1.__proto__[@@species] → Array[@@species] を取得する。 Array[@@species]はレシーバ(this)を返す仕様のため、 結果MyArray1が返され、これが種族コンストラクタとして扱われる。 (よって通常MyArray1クラスに@@speciesゲッタを定義しておく必要はない。) */ console.log( a1 instanceof MyArray1 ) // true
@@species有り→MyArray1:
class MyArray2 extends Array { static get [Symbol.species]() { return MyArray1 } } let a2 = new MyArray2(1, 2, 3) a2 = a2.map( v => v + 1 ) // [2, 3, 4] /*map内部の処理 a2はArrayのサブクラスのため、 a2.constructor[@@species] → MyArray2[@@species] を取得する。 結果MyArray1が返され、これが種族コンストラクタとして扱われる。 */ console.log( a2 instanceof MyArray1 ) // true console.log( a2 instanceof MyArray2 ) // false a2.clear() // 使える
実装されるバージョン
V8 4.9.285 -