Older browser support: So, redefining
Object.defineProperty
where it's not defined.
You can't do that with your current approach, because your current approach extends Object.prototype
. Extending Object.prototype
should very, very rarely be done if you have ES5 support, but it must never be done without it, because without Object.defineProperty
, you have no way to create a non-enumerable property. Adding enumerable properties to Object.property
will break all of your for-in
loops.
There's no reason for Enum
to be on the prototype anyway, though, just put it on Object
(or your own library object) and pass the object to be enum-ified into it.
Any considerations I may have missed it the Enum definition.
It seems to me that this offers little on top of:
var obj = Object.freeze({
"RED": 0,
"GREEN": 1,
"BLUE": 2
});
You might wrap that up into a function that will work, without freezing the object, in pre-ES5 environments, e.g.:
function createEnum(spec) {
if (Object.freeze) {
spec = Object.freeze(spec);
}
return spec;
}
You can enhance that, of course, if you want the automatic values, e.g:
function createEnum(spec) {
var obj = {}, n;
if (Object.prototype.toString.call(spec) === "[object Array]") { // No isArray pre ES5
for (n = 0; n < spec.length; ++n) {
if (spec[n] != null) { // checks for null or undefined
obj[spec[n]] = n;
}
}
}
else {
for (n in spec) {
if (spec.hasOwnProperty(n)) {
obj[n] = spec[n];
}
}
}
if (Object.freeze) {
obj = Object.freeze(obj);
}
return obj;
}
You could put that on Object
(not Object.prototype
), if you liked.
Below you've said that you don't want to use freeze
because it makes the object non-extensible. Fair enough, wanting to add further enum values later. The above is easily adapted to doing that, using Object.defineProperty
if present and falling back on just assigning the property if not.