1
\$\begingroup\$

When developing in Javascript, it seems useful especially for event systems to use enum-likes, but not string comparison for performance considerations (also because it doesn't protect against typos). How do you use Enums in JS? Should I switch to Typescript?

\$\endgroup\$
1
  • 2
    \$\begingroup\$ This question looks like it applies to Javascript development generally, not just to games. So you may get answers faster by asking on our general programming sister site StackOverflow. In fact, you may find it's already been answered there. \$\endgroup\$
    – DMGregory
    Jul 19, 2018 at 10:25

2 Answers 2

2
\$\begingroup\$

Use Symbols.

Symbols are unique. Even if you pass the same value to them, they won't be the same.

let MY_ENUM = Symbol(1);
let MY_ENUM2 = Symbol(2);

alert(MY_ENUM == MY_ENUM2); // false

So store these in an object. To make sure the enum you reveive in a function is of a certain type, just use the in keyword.

let myEnumObj = {
    MY_ENUM: Symbol(1)
};

function foo(bar) {
    if (bar in myEnumObj) { ... } 
} 
\$\endgroup\$
5
  • \$\begingroup\$ The idea is that I'd use something like a set of enums (think token types) as an import directly, like if (token.type = tokens.PLUS)... And I'd get an error when typing in "tokens.PLOS", instead of "undefined" \$\endgroup\$ Jul 19, 2018 at 11:48
  • 1
    \$\begingroup\$ @AlexMitan JavaScript is a dynamically typed language, so it's very difficult for the interpreter to recognize if an undefined variable or object property will always be undefined. You can usually only catch errors like this at runtime. \$\endgroup\$
    – Philipp
    Jul 19, 2018 at 12:48
  • \$\begingroup\$ Make sure you use a triple equal sign (===) in comparison in JavaScript for both value and type comparison. \$\endgroup\$
    – Chad
    Aug 22, 2018 at 17:45
  • \$\begingroup\$ @Chad in this case it's not necessary, since a symbol is always completely unique, even Symbol(1) == Symbol(1) returns false. So you'll need to pass the same one aroumd \$\endgroup\$
    – Bálint
    Aug 22, 2018 at 18:41
  • \$\begingroup\$ Fair enough, thank you for explaining! +1 \$\endgroup\$
    – Chad
    Aug 22, 2018 at 20:11
0
\$\begingroup\$

I also use Symbols, and have implemented them in an object literal like below using a setter.

I am using the object key as the string description inside () for easier debugging, and throw an error if the key is invalid.

export default {

  currentScreen: null,

  SCREEN: {
    TITLE_SCREEN: Symbol('TITLE_SCREEN'),
    GAME_SCREEN: Symbol('GAME_SCREEN'),
    PAUSE: Symbol('PAUSE'),
    GAMEOVER_SCREEN: Symbol('GAMEOVER_SCREEN'),
  },

  set setScreen(key) {
    if (key in this.SCREEN) {
      this.currentScreen = this.SCREEN[key];
    } else {
      throw new TypeError(`${key} is invalid key for SCREEN object`);
    }
  },

}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .