Skip to content

Instantly share code, notes, and snippets.

@jmar777
Created June 21, 2016 04:36
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jmar777/d151d7112059a1716aa1ecba699fe6fc to your computer and use it in GitHub Desktop.
Save jmar777/d151d7112059a1716aa1ecba699fe6fc to your computer and use it in GitHub Desktop.
Enum Implementation using ES6 Proxies and Symbols
function Enum(names) {
let members = Object.create(null);
members.tryParse = name => {
if (!members[name]) {
throw new Error(`Unable to parse '${name}' as an Enum member.`);
}
return members[name];
};
names.forEach(name => members[name] = Symbol(name));
return new Proxy(members, {
get: (target, name) => {
if (!members[name]) {
throw new Error(`Member '${name}' not found on the Enum.`);
}
return members[name];
},
set: (target, name, value) => {
throw new Error('Adding new members to Enums is not allowed.');
}
});
}
@jmar777
Copy link
Author

jmar777 commented Jun 21, 2016

Motivation: mostly just to play around with some new concepts, but also to combat some of the deficiencies exhibited by most faux Enum implementations (e.g., producing undefined for unknown keys).

Usage:

let PrimaryColors = Enum(['RED', 'GREEN', 'BLUE']);

PrimaryColors.RED === PrimaryColors.RED; // true

PrimaryColors.RED === 'RED'; // false

PrimaryColors.RED === PrimaryColors.tryParse('RED'); // true

console.log(PrimaryColors.PINK); // throws

PrimaryColors.ORANGE = 'ORANGE'; // throws

Play around with it on JSBin.

@jzaefferer
Copy link

Very nice! I needed a key/value enum, which works almost the same: http://jsbin.com/wapugek/edit?js,output

function Enum(props) {
  const members = Object.create(null);
  
  Object.keys(props)
    .forEach(name => members[name] = props[name]);
  
  return new Proxy(members, {
    get: (target, name) => {
      if (!members[name]) {
        throw new Error(`Member '${name}' not found on the Enum.`);
      }
      return members[name];
    },
    set: (target, name, value) => {
      throw new Error('Adding new members to Enums is not allowed.');
    }
  });
}

@jmar777
Copy link
Author

jmar777 commented Feb 16, 2017

@jzaefferer I like that! Mine was a bit of a quick hack for a specific use-case, but obviously doesn't factor in, e.g., serializability (looking back, I can't even remember why I went with Symbol values, vs. assigning a more traditional ordinal value). Thanks for sharing the improvements.

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