Created
June 9, 2012 02:42
-
-
Save dherman/2899176 to your computer and use it in GitHub Desktop.
Map vs object for dictionary
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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); | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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]; | |
} | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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]; | |
}; |
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
@dherman, oh.. sorry, you are right, defineGetter is inherited from Object.prototype
but
have you any information, that in the future no other "magic" properties will be added?