Skip to content

Instantly share code, notes, and snippets.

@dherman
Created June 9, 2012 02:42
Show Gist options
  • Save dherman/2899176 to your computer and use it in GitHub Desktop.
Save dherman/2899176 to your computer and use it in GitHub Desktop.
Map vs object for dictionary
// A Dict class that works in ES6 using Map. Basically it's identical to Map, but
// only expected to be used on string keys.
function Dict() {
this.elts = new Map();
}
// (string) -> any
Dict.prototype.get = function get(key) {
return this.elts.get(key);
};
// (string, any) -> void
Dict.prototype.set = function set(key, val) {
return this.elts.set(key, val);
};
// (string) -> boolean
Dict.prototype.has = function has(key) {
return this.elts.has(key);
};
// (string) -> void
Dict.prototype.remove = function remove(key) {
this.elts.delete(key);
};
// A Dict class that works in ES5, or in engines that support __proto__ so that
// a polyfilled Object.create can create prototype-less objects. This hasn't been
// tested or optimized at all. I'll accept any optimizations so long as it's
// never sensitive to prototype pollution (e.g. in Object.prototype).
function Dict() {
this.dunderProto = Object.create(null);
this.elts = Object.create(null);
}
// (string) -> any
Dict.prototype.get = function get(key) {
return (key === '__proto__') ? this.dunderProto.value : this.elts[key];
};
// (string, any) -> void
Dict.prototype.set = function set(key, val) {
if (key === '__proto__') {
this.dunderProto.value = val;
} else {
this.elts[key] = val;
}
};
// (string) -> boolean
Dict.prototype.has = function has(key) {
return (key === '__proto__') ? 'value' in this.dunderProto : key in this.elts;
};
// (string) -> void
Dict.prototype.remove = function remove(key) {
if (key === '__proto__') {
delete this.dunderProto.value;
} else {
delete this.elts[key];
}
};
// Alternative implementation that protects against magic __proto__ by prefixing
// all keys with "%". Again, works in ES5 or in engines that support __proto__ so
// that a polyfilled Object.create can create prototype-less objects.
function Dict() {
this.elts = Object.create(null);
}
// (string) -> any
Dict.prototype.get = function get(key) {
return this.elts["%" + key];
};
// (string, any) -> void
Dict.prototype.set = function set(key, val) {
this.elts["%" + key] = val;
};
// (string) -> boolean
Dict.prototype.has = function has(key) {
return ("%" + key) in this.elts;
};
// (string) -> void
Dict.prototype.remove = function remove(key) {
delete this.elts["%" + key];
};
@dherman
Copy link
Author

dherman commented Jun 9, 2012

Yes, because they were one of the worst mistakes ever made in JS. I can't guarantee that no one will do it again, but I can tell you that as long as Brendan and I have anything to do with it, we won't let it happen.

Dave

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