Javascript Array of Instances of a class

Viewed 40112

In JS, I have a class called player which is:

class player {
    constructor(name) {
        this.name = name;
    }
}

and I have two instances of it, called PL1 and PL2:

const PL1 = new player ('pl1name');
const PL2 = new player ('pl2name');

I also have an array called PLAYERS:

let PLAYERS = [];

now, the question is how can I create an array with all of the instances of the class player?

I know I can manually do this with PLAYERS.push(PLn); but I'm looking for a way to do this somehow automatically. Is there a built-in function? Should I use a loop?

5 Answers

You could create a class that is a container class for the players. This will allow the container to create players and manage them. The the Players class can expose an interface making it easy to interact with the players individually or as a whole. Something like this might be a good start and could be filled out with more functionality or different orginziation:

// An individual player. Holds properties and behavior for one player
class Player {
  constructor(name) {
      this.name = name;
  }
  play() {
    console.log(this.name, "plays")
  }
}

// Class that holds a collection of players and properties and functions for the group
class Players {
  constructor(){
    this.players = []
  }
  // create a new player and save it in the collection
  newPlayer(name){
    let p = new Player(name)
    this.players.push(p)
    return p
  }
  get allPlayers(){
    return this.players
  }
  // this could include summary stats like average score, etc. For simplicy, just the count for now
  get numberOfPlayers(){
      return this.players.length
  }
}

let league = new Players()
league.newPlayer("Mark")
league.newPlayer("Roger")

// list all the players
console.log(league.numberOfPlayers + " Players)
console.log(league.allPlayers)


// make them do something
league.allPlayers.forEach(player => player.play())

To initialize an Array with a static amount of Player objects, you could call new Player() in the array:

const players = [new Player('name1'), new Player('name2'), new Player('name3')];

You could also dynamically create your player list using a loop:

const playerNames = ['name1', 'name2', 'name3'];
let players = [];
playerNames.forEach((playerName) => players.push(new Player(playerName)));

I can't comment your answer as of now so here's an addition:

class player {
    constructor(name){
        this.name = name;
        PLAYERS.push(this);
    }
}

PLEASE: be aware there's a whole lot of awful practices in this few lines, you shouldn't tie a constructor to a variable that may or may not be initialized somewhere else, meddling with the constructor with whatever external is plain awful. Also classes are usually title-cased.

Plus as a side note, while it's real that you can change consts properties while maintaining the reference, so you can push objects in an array that's declared as const, it really doesn't add up as self-documenting code, so, if you are going to modify this array, just declare it with "let" from the start.

Actually you just want to write the data to the array. So you need a two dimensional array.

Next you can write or read the values to and from the array.

class player {
constructor(name, val, ...) {
    this.name = name;
    this.val = val; // ....
}

toarr()
{
arr=[];
arr[0] = this.name;
arr[1] = this.val; //etcetera
return arr;
}

fromarr(arr){
this.name = arr[0];
this.val = arr[1]
...
}   
}

actually you need just one instance of player, and reset the values everytime to access or create other players.

reset( name, val){
this.name = name;
this.val = val; // ....}

so, code equal to the constructor.

eventually the array of all players will look somewhat like this:

players = [];
current_player = new player (name, val);
players[0] = current_player.toarr();
current_player.reset(name1, val1);
players[1] = current_player.toarr();

or

current_player.fromarr[24];

(note you could also write code like current_player.byname(name))

If you want to compare two players, or all players, you just need two instances of player.

When writing to a two dimensional array, you can use named values. I like it this way.

const NAME = 0;
const VAL = 1;
etcetera 

You can easily add a value to the array, by adding a val2 (weight, length, income, likes) You can even add names_of_children; an array within the 2 dimensional array. But this might cause some problems.

To compare players, or to sort players, you could also just access the array.

If you write all code in a seperated file, and this file is only loaded if you access and manipulate data of the players, you do not have to make a class of het array, it could as well be a module.

if (we_use_the_players_array === true) {do load the players.js file} 

refreshing the whole page, so other ... .js files are not used

You can push every instance into a static array of the class as part of your constructor method. (In the most basic form this could look something like the code below)

This answer explains it a bit more: https://stackoverflow.com/a/71696802/19529102

The linked answer also provides an improvement which fixes the flaw, that in this basic version the array is directly exposed/returned

class Player {

    static all = [];

    constructor(name) {
        this.name = name;
        Player.all.push(this);
    }
}

const PL1 = new Player("pl1name");
const PL2 = new Player("pl2name");

console.log(Player.all);
console.log(PL1.all); //undefined; instance of Player does not inherit all

const PL3 = new Player("pl3name");

console.log(Player.all);

Related