2

Suppose I have a class like this:

let initPack = { player: [] };
let Player = function(param) {
  let self = {
    id: param.id,
    x: param.x,
    y: param.y
  }

  self.update = function() {
    self.x += 1;
    self.y += 1;
  }

  self.getInitPack = function() {
    return {
      id: self.id,
       x: self.x,
       y: self.y
    }
  }

  Player.list[self.id] = self;
  initPack.player.push(self.getInitPack());
  return self;
}

Player.list = {};

If I want to rewrite this to ES6 classes and put it into a separate file in node.js, such as:

module.exports = class Player {
  constructor(param) {
     this.id = param.id;
     this.x = param.x;
     this.y = param.y;
  }

  update() {
     this.x += 1;
     this.y += 1;
  }

  getInitPack() {
    return {
      id: self.id,
       x: this.x,
       y: this.y
    }
  }
}

How can I rewrite the rest of the class to make it work like the previous one? There are some static members and use of external variables in the original file. But I am not sure how to do that correctly in ES6.

newguy
  • 5,668
  • 12
  • 55
  • 95
  • How do you intend to handle `initPack`? Do you want it also to be a "static field" of `Player`? – 4castle Sep 04 '16 at 06:14
  • 2
    Possible duplicate of [Modern way to create static or Class variable for Javascript class](http://stackoverflow.com/questions/37982610/modern-way-to-create-static-or-class-variable-for-javascript-class) – 4castle Sep 04 '16 at 06:22
  • @4castle That's the problem I want to solve. `initPack` was not a static member but a global variable which was used in somewhere else in the project. Each time I instantiate a `Player` object it will be pushed into the static list and its initial data will be pushed into `initPack`'s player array. Do I have to use an `init` method in the class? That seems a bit odd because now I have to init the class before I can use static members. – newguy Sep 04 '16 at 06:32
  • You can put the `Player.list[self.id]` and the `push` statement in the constructor. Just replace `self` with `this`. – 4castle Sep 04 '16 at 06:37
  • There isn't any syntactic sugar for static properties in ES6. That custom `init` function is a workaround, but notice that it gets called and deleted from the class immediately after the class declaration, so you don't have to worry about initializing the static members later. – 4castle Sep 04 '16 at 06:39
  • "*`self.update() {`*" appears to be a syntax error – Bergi Sep 04 '16 at 11:21
  • @Bergi Just typo, sorry. – newguy Sep 04 '16 at 12:19

1 Answers1

1

You would put these things just inside the constructor or next to the class as you did before.

class Player {
  constructor(param) {
    this.id = param.id;
    this.x = param.x;
    this.y = param.y;

    Player.list[this.id] = this;
    initPack.player.push(this.getInitPack());
  }
  update() {
    …
  }
  getInitPack() {
    …
  }
}
Player.list = {};
const initPack = { player: [] };

module.exports = Player;

You should however notice that such global singleton storages are an antipattern, and even if you really need them you should better decouple them from the construction.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Yes I notice that. So I am looking for an OO way for this problem. I don't want to use global variable in a class module. – newguy Sep 04 '16 at 16:35
  • Make an extra class for the lists and packs then and give them an `addPlayer` method that either takes a player instance as an argument or creates it. Instantiate the store where you need it (e.g. once per game). – Bergi Sep 04 '16 at 20:57