Grauw’s blog
JavaScript enumeration pattern
Although often better handled with subclasses and polymorphism, enumerations can be a convenient light-weight way to indicate some kind of state or non-boolean flag.
When one makes an enumeration in JavaScript, it is typically an old-fashioned list of constants with integer number values:
var MyEnum = {};
MyEnum.FIRST = 0;
MyEnum.SECOND = 1;
MyEnum.THIRD = 2;
A downside of this approach is that it is not type-safe; these values can not be distinguished from any other number. Additionally, it is possible to cheat by hardcoding a value somewhere, which makes code less readable and refactoring a lot harder.
There is a better way however:
function MyEnum() {}
MyEnum.FIRST = new MyEnum();
MyEnum.SECOND = new MyEnum();
MyEnum.THIRD = new MyEnum();
When one of these is passed to a method its type can be checked using instanceof
or a function like checkTypes()
. And because these are unique object references they are impossible to specify without using the constants.
Additionally, because this effectively defines a class it comes with a lot of power. E.g. you can pass meta-data and handy functions:
function MyEnum(name) { this._name = name; }
MyEnum.prototype.toString = function() { return this._name; };
MyEnum.FIRST = new MyEnum("FIRST");
MyEnum.SECOND = new MyEnum("SECOND");
MyEnum.THIRD = new MyEnum("THIRD");
Finally, as you discover you want to move more and more functionality onto this enumeration, it is easy to upgrade the enumeration to a full-fledged set of subclasses:
function First() {
MyEnum.call(this, "FIRST");
}
extend(MyEnum, First);
function Second() {
MyEnum.call(this, "SECOND");
}
extend(MyEnum, Second);
function Third() {
MyEnum.call(this, "THIRD");
}
extend(MyEnum, Third);
Grauw
Comments
None.