The @@species
accessor property returns the default constructor for typed array objects. Subclass constructors may override it to change the constructor assignment. The default implementation is basically:
class TypedArray {
static get [Symbol.species]() {
return this;
}
}
Because of this polymorphic implementation, @@species
of derived subclasses would also return the constructor itself by default.
class SubTypedArray extends Int8Array {}
SubTypedArray[Symbol.species] === SubTypedArray;
When calling typed array methods that do not mutate the existing array but return a new array instance (for example, filter()
and map()
), the array's constructor[@@species]
will be accessed. The returned constructor will be used to construct the return value of the typed array method.
However, unlike Array[@@species]
, when using @@species
to create new typed arrays, the language will make sure that the newly created array is a proper typed array and has the same content type as the original array — for example, you can't create a BigInt64Array
from a Float64Array
, or create a non-BigInt array from a BigInt array. Doing so throws a TypeError
.
class BadArray extends Int8Array {
static get [Symbol.species]() {
return Array;
}
}
new BadArray(1).map(() => 0);
class BadArray2 extends Int8Array {
static get [Symbol.species]() {
return BigInt64Array;
}
}
new BadArray2(1).map(() => 0n);
Note: Due to a bug in both SpiderMonkey and V8, the content type match is not checked. Only Safari will throw a TypeError
in the second example.