-
-
Save dherman/2899176 to your computer and use it in GitHub Desktop.
// 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]; | |
}; |
Yaffle
commented
Jun 9, 2012
Pretty sure those have been gone for a while, no?
Dave
@dherman, http://kangax.github.com/es5-compat-table/non-standard/
although, may be some properties (defineGetter) could be removed
delete x.__defineGetter__
Yeah, defineGetter isn't a problem because it's inherited from Object.prototype. I'm not worried about count or parent because I'm more interested in the future. (Of course, if someone wants to make this compatible back to FF 3.6 they can put in additional special cases for count and parent as well.)
Dave
@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?
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