# JS Tip of the Day: Symbol.species

**URL:** <https://forum.kirupa.com/t/js-tip-of-the-day-symbol-species/643121>\
**Category:** web dev\
**Created:** [April 15, 2020, 1:33pm UTC](https://forum.kirupa.com/t/js-tip-of-the-day-symbol-species/643121 "2020-04-15T13:33:40Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![senocular](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/senocular/32/7217_2.png) [@senocular](https://forum.kirupa.com/u/senocular)\
**Post date:** [April 15, 2020, 1:33pm UTC](https://forum.kirupa.com/t/js-tip-of-the-day-symbol-species/643121/1 "2020-04-15T13:33:40Z")

</div>

**Symbol.species**  
Version: ES2015  
Level: Advanced

The species of an object is used to determine the kind of objects it creates when creating derived versions of itself. The `slice()` method of arrays, for example, creates and returns a new array when its called. If you were to extend Array to create your own custom array class, `slice()` called from instances of that class would create new instances of the custom array class rather than normal arrays.

```javascript
console.log(new Array(1, 2, 3).slice(1) instanceof Array); // true

class CustomArray extends Array {}
let sliced = new CustomArray(1, 2, 3).slice(1);
console.log(sliced instanceof CustomArray); // true

```

By default the species will use the current class to create derived instances, but you can specify a new type by creating a static `Symbol.species` property on the class. The value of this property will represent the constructor to use for derived instances.

```javascript
class CustomArray extends Array {
    static get [Symbol.species] () {
        return Array; // normal arrays now the species
    }
}

let sliced = new CustomArray(1, 2, 3).slice(1);
console.log(sliced instanceof CustomArray); // false
console.log(sliced instanceof Array); // true

```

Constructors used from species should have the same signature as those used by the base type. In the case of Array species, this means a single numeric length argument or any number of other arguments representing the elements of the array. If you have an Array subclass that has special constructor requirements, you may want to use `Array` for its species (as seen above) so methods like `slice()` won’t fail when they attempt to create new instances for their return values.

`Symbol.species` is supported by Array (including typed arrays and array buffers), Promise, and RegExp. Map and Set also define a `Symbol.species` property, but there’s nothing in place within their current API that uses it. The expectation is that if you (or anyone else) extended these types, the species would be used for new instances if they were needed.

```javascript
class SlicableSet extends Set {
    slice (begin, end) {
        let Species = this.constructor[Symbol.species];
        return new Species(
          Array.from(this)
            .slice(begin, end)
        );
    }
}

let pizza = new SlicableSet([1,2,3,4,5,6]);
let plate = pizza.slice(1,3);
console.log(plate instanceof SlicableSet); // true
console.log(plate); // SlicableSet {2, 3}

```

Species can be also important for promises. This is because promises create new promises via species for every call to `then()`, `catch()`, and `finally()`. As part of a promise chain, you may not want the behavior of your custom promise to be propagated through the rest of the entire chain. We’ll explore this specific case more in a future tip.

More info:

- [Symbol.species on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/species)
- [Array.@@species on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/@@species)
- [RegExp.@@species on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@species)
- [Map.@@species on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/@@species)
- [Set.@@species on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/@@species)
