Skip to content

Instantly share code, notes, and snippets.

@o0101
Created October 3, 2021 17:15
Show Gist options
  • Save o0101/a0256dcdf8f8973d05675edc34258d8c to your computer and use it in GitHub Desktop.
Save o0101/a0256dcdf8f8973d05675edc34258d8c to your computer and use it in GitHub Desktop.
Enums in JavaScript
class Enum extends Function {
static opts = { enumerable: true, writeable: true, configurable: false };
constructor() {
super();
const names = (this.constructor+'').split('{')[1].split('}')[0].split(';').map(n => n.trim()).filter(n => n);
names.forEach((name, i) => {
Object.defineProperty(this.constructor, name.slice(1), { get: () => i, set: () => true, ...Enum.opts });
});
return this.constructor;
}
}
const Day = new class extends Enum { $MONDAY; $TUESDAY; $WEDNESDAY; };
const day = Day.MONDAY;
function enum_(strings, ...values) {
const str = strings.join('');
const names = str.split(/[;.,]/g).map(n => n.trim()).filter(n => n);
const e = Object.create(null);
names.forEach((name, i) => e[name] = i);
return e;
}
const Name = enum_`Fred, Cris, Harry, Megan`;
const personName = Name.Fred;
@o0101
Copy link
Author

o0101 commented Oct 3, 2021

Syntax 1:

const Day = new class extends Enum { $MONDAY; $TUESDAY; $WEDNESDAY; };

Advantages: You get to say "new class extends Enum" which semantically sounds like an Enum.
Disadvantages: The first character of each constant is silent (but necessary to hack the class syntax in the way we are doing).

Syntax 2:

const Name = enum_`Fred, Cris, Harry, Megan`;

Advantages: Terser, straightforward
Disadvantages: Less "syntactically semantic", it's just a template tag function with a string. It's not a class or a type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment