The Team Stats practice project. Shouldn't we use setter to add additional players and games?

When I faced the task where we need to create a method to add more players and games to our certain properties ( _players and _games) I can’t understand why we don’t try to use here setter because it seems to me that it must be also confidential information. Why do we just use the default function?
If someone knows please tell me.

  • my final code:
// Los Angeles Lakers of the 2015-2016 NBA season.
// In the final game of that season and also his career, Kobe Bryant scored 60 points. It's something incredible.

const team = {
  _players: [
    { firstName: "Kobe", lastName: "Bryant", age: 37 },
    { firstName: "Jordan", lastName: "Clarkson", age: 24 },
    { firstName: "D'Angelo", lastName: "Russell", age: 20 },
    { firstName: "Julius", lastName: "Randle", age: 22 },
    { firstName: "Roy", lastName: "Hibbert", age: 30 },
  ],
  _games: [
    { opponent: "Utah Jazz", teamPoints: 101, opponentPoints: 96 },
    { opponent: "Oklahoma City Thunder", teamPoints: 79, opponentPoints: 112 },
    { opponent: "Houston Rockets", teamPoints: 110, opponentPoints: 130 },
    { opponent: "New Orleans Pelicans", teamPoints: 102, opponentPoints: 110 },
    { opponent: "Los Angeles Clippers", teamPoints: 81, opponentPoints: 91 },
  ],
  get players() {
    return this._players;
  },
  get games() {
    return this._games;
  },
  addPlayer(newFirstName, newLastName, newAge) {
    let player = {
      firstName: newFirstName,
      lastName: newLastName,
      age: newAge,
    };
    return this._players.push(player);
  },
  addGame(newOpponent, newTeamPoints, newOpponentPoints) {
    let game = {
      opponent: newOpponent,
      teamPoints: newTeamPoints,
      opponentPoints: newOpponentPoints,
    };
    return this._games.push(game);
  },
  checkStats() {
    console.log('\nMembers of the Los Angeles Lakers during the 2015-2016 NBA season:\n')
    this.players.forEach(function(players){
      console.log(`Player: ${players.firstName} ${players.lastName} , Age: ${players.age}`);
    });
    console.log('\n\nThe last 10 games of those years:\n')
    this.games.forEach(function(games){
      console.log(`Opponent: ${games.opponent}, Team points: ${games.teamPoints}, Opponent points: ${games.opponentPoints}`)
    });
  },
};

const additionalPlayers = [
  { firstName: "Lou", lastName: "Williams", age: 30 },
  { firstName: "Larry", lastName: "Nance", age: 23 },
  { firstName: "Brandon", lastName: "Bass", age: 31 },
  { firstName: "Marcelo", lastName: "Huertas", age: 33 },
  { firstName: "Tarik", lastName: "Black", age: 25 },
];

additionalPlayers.forEach(function (element) {
  return team.addPlayer(element.firstName, element.lastName, element.age);
});

const previousFiveGames = [
  { opponent: "Utah Jazz", teamPoints: 101, opponentPoints: 96 },
  { opponent: "Los Angeles Clippers", teamPoints: 81, opponentPoints: 103 },
  { opponent: "Boston Celtics", teamPoints: 100, opponentPoints: 107 },
  { opponent: "Miami Heat", teamPoints: 102, opponentPoints: 100 },
  { opponent: "Utah Jazz", teamPoints: 75, opponentPoints: 123 },
];

previousFiveGames.forEach(function (element) {
  team.addGame(element.opponent, element.teamPoints, element.opponentPoints);
});

team.checkStats();

Link: https://www.codecademy.com/journeys/full-stack-engineer/paths/fscj-22-building-interactive-websites/tracks/fscp-22-javascript-syntax-part-ii-c8ddbace-1463-4797-ae12-503c7b0f9552/modules/wdcp-22-learn-javascript-syntax-objects-42047fd1-bfb5-4b90-96a5-431acbee8013/projects/team-stats

This is a little confusing, indeed.

Private properties in Javascript

First of all, there are no ‘confidential’ or private properties in your code. You can access properties that are marked as private with the underscore from the outside like so:

const team = {
  _players: [{ firstName: "Kobe", lastName: "Bryant", age: 37 }]
};

console.log(team._players[0].firstName) // "Kobe"

The underscore is just a convention to pretend privacy of a property and indicate that the above way to access it should be avoided. That convention was established because Javascript did not have a distinction between private and public for a long time, but programmers from other languages were used to that concept and wanted to simulate it in Javascript, too. In the meantime, there are real private properties in Javascript, suffixed with a #. This syntax does not have a huge fanbase, though.

When to use setters or a method

Usually, setters should have corresponding getters. It would be difficult to have a getter for additional players because you wouldn’t know which players were added and which were there initially. But even in the MDN docs this concept is not very strict.

For the concept of privacy, it does not matter if you add the additional players with a setter or a public method like addPlayer() as you do not access a private property directly from the outside.

Differences of setters and methods

There are syntax differences between setters and methods. You cannot have multiple arguments when using setters. If you want to add a player with a setter, you would have to assign the whole object:

const team = {
  _players: [{ firstName: "Kobe", lastName: "Bryant", age: 37 }],
  set player(player) {
    this._players.push(player)
  }
};
team.player = { firstName: "Jordan", lastName: "Clarkson", age: 24 }

It might rather make sense to use a setter to replace the whole _players array like so:

const team = {
  _players: [{ firstName: "Kobe", lastName: "Bryant", age: 37 }],
  get players() {
   return this._players
  },
  set players(players) {
    this._players = players
  }
};
const players = [
{ firstName: "Jordan", lastName: "Clarkson", age: 24 },
{ firstName: "D'Angelo", lastName: "Russell", age: 20 }
]
team.players = players
console.log(team.players) 
/* [{
  age: 24,
  firstName: "Jordan",
  lastName: "Clarkson"
}, {
  age: 20,
  firstName: "D'Angelo",
  lastName: "Russell"
}]
*/

That way you can have a corresponding getter. Additional players could still be added with the method.

1 Like