JavaScript Array inheritance

An array is the simplest way to define a set of data. But sometimes the basic features of arrays may not be enough. For example, let’s define an array that represents some command:

const team = ["Tom", "Sam", "Bob"];
for(const person of team) {
    console log(person);
}

But what if we want to add some additional attributes to the team – the name of the coach, the country or city where the team is based, the name, some other features? At first glance, we can define a complex object:

const team = {
    name: "Barcelona", // name
    members: ["Tom", "Sam", "Bob"] // players
};
for(const person of team.members) {
    console log(person);
}

But there is another solution that allows us to define our own collection type: create our own class that will be inherited from Array.

class Team extends Array{
    
    constructor(name, ...members){
        super(...members);
        this.name = name;
    }
}

Here we assume that the first parameter of the class constructor is the name of the team, and the second parameter is a set of team players, the number of which is not fixed.

By inheriting from Array, we can treat Team objects as collections of data and apply to them all the same operations that apply to arrays:

class Team extends Array{
    
    constructor(name, ...members){
        super(...members);
        this.name = name;
    }
}
// create command object
const barcelona = new Team("Barcelona", "Tom", "Sam", "Bob");
console log(barcelona); // Team(3) ["Tom", "Sam", "Bob"]

// iterate over the set
for(const person of barcelona) {
    console log(person);
}
barcelona.push("Tim"); // add one element
console log(barcelona); // Team(4) ["Tom", "Sam", "Bob", "Tim"]
barcelona splice(1, 1); // remove the second element
console log(barcelona); // Team(3) ["Tom", "Bob", "Tim"]

Overriding Methods

As in general, when inheriting, we can override inherited methods. For example, let’s redefine the behavior of the push() add method, which is responsible for adding to the end of the array:

class Team extends Array{
    
    constructor(name, ...members){
        super(...members);
        this.name = name;
    }
    push(person){
        if(person !== "admin") super.push(person);
    }
}

const snowbars = new Team("SnowBars", "Tom", "Sam", "Bob");

snowbars.push("admin"); // add one element - admin
console log(snowbars); // Team(3) ["Tom", "Sam", "Bob"]
snowbars.push("Tim"); // add one element - Tim
console log(snowbars); // Team(4) ["Tom", "Sam", "Bob", "Tim"]

In this case, if any name other than “admin” is passed to the method, then it is added to the command.