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 September 2016.
TheSymbol.species static data property represents thewell-known symbolSymbol.species. Methods that create copies of an object may look up this symbol on the object for the constructor function to use when creating the copy.
Warning:The existence of[Symbol.species] allows execution of arbitrary code and may create security vulnerabilities. It also makes certain optimizations much harder. Engine implementers areinvestigating whether to remove this feature. Avoid relying on it if possible.
In this article
Try it
class Array1 extends Array { static get [Symbol.species]() { return Array; }}const a = new Array1(1, 2, 3);const mapped = a.map((x) => x * x);console.log(mapped instanceof Array1);// Expected output: falseconsole.log(mapped instanceof Array);// Expected output: trueValue
The well-known symbolSymbol.species.
Property attributes ofSymbol.species | |
|---|---|
| Writable | no |
| Enumerable | no |
| Configurable | no |
Description
The[Symbol.species] accessor property allows subclasses to override the default constructor for objects. This specifies a protocol about how instances should be copied. For example, when you use copying methods of arrays, such asmap(), themap() method usesinstance.constructor[Symbol.species] to get the constructor for constructing the new array. For more information, seesubclassing built-ins.
All built-in implementations of[Symbol.species] return thethis value, which is the current instance's constructor. This allows copying methods to create instances of derived classes rather than the base class — for example,map() will return an array of the same type as the original array.
Examples
>Using species
You might want to returnArray objects in your derived array classMyArray. For example, when using methods such asmap() that return the default constructor, you want these methods to return a parentArray object, instead of theMyArray object. Thespecies symbol lets you do this:
class MyArray extends Array { // Overwrite species to the parent Array constructor static get [Symbol.species]() { return Array; }}const a = new MyArray(1, 2, 3);const mapped = a.map((x) => x * x);console.log(mapped instanceof MyArray); // falseconsole.log(mapped instanceof Array); // trueSpecifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-symbol.species> |