A lightweight but safe dictionary, for when Object won't cut it
CoffeeScript JavaScript
Switch branches/tags
Clone or download
Latest commit a498f77 Oct 28, 2017


An Easy But Safe String-Keyed Store

Don't stuff things into objects. Use a Dict instead.

The Problem

You're probably used to stuffing things into objects:

var hash = {};

hash["foo"] = "bar";

console.log("foo" in hash ? hash["foo"] : "not there"); // "bar"

However this doesn't always work, because your naïve hashes inherit from Object.prototype:

var hash = {};

console.log("hasOwnProperty" in hash); // true!

Even worse, the magic __proto__ property can really ruin your day:

var hash = {};
var anotherObject = { foo: "bar" };

hash["__proto__"] = anotherObject;

console.log("foo" in hash);       // true!!
console.log("__proto__" in hash); // false!!!

Usually you're smart enough to avoid silly key names like "hasOwnProperty", "__proto__", and all the rest. But sometimes you want to store user input in your hashes. Uh-oh…

Dict Is the Solution

Just do an npm install dict --save and you're ready to use this nice-looking API:

var dict = require("dict");

var d = dict({
    IV: "A New Hope",
    V: "The Empire Strikes Back",
    VI: "Return of the Jedi"

d.has("IV");                      // true
d.get("V");                       // "The Empire Strikes Back"
d.size;                           // 3

d.has("I");                       // false
d.set("I", "The Phantom Menace"); // "The Phantom Menace"
d.get("I");                       // "The Phantom Menace"
d.delete("I");                    // true
d.get("I");                       // undefined
d.get("I", "Jar-Jar's Fun Time"); // "Jar-Jar's Fun Time"

d.forEach(function (value, key) {
   console.log("Star Wars Episode " + key + ": " + value);

d.size;                           // 0

And of course, Dict prides itself in being bulletproof against all that nastiness we talked about earlier:

var d = dict();

d.set("foo", "bar");
console.log(d.get("foo", "not there")); // "bar"

console.log(d.has("hasOwnProperty"));   // false

var anotherObject = { baz: "qux" };
d.set("__proto__", anotherObject);
console.log(d.has("baz"));              // false
console.log(d.has("__proto__"));        // true


  • A lightweight ES6-inspired API:
    • get, set, has and delete basic operations.
    • A size property and forEach method for introspection.
    • A clear method for clearing out all keys and values.
  • get accepts a second argument as a fallback for if the key isn't present (like Mozilla's WeakMap).
  • set returns the value set, just like assignment to an object would.
  • Doesn't let you get away with being dumb: if you pass a non-string as a key, you're going to get a TypeError.

See Also

  • rauschma/strmap for something a bit more full-featured (albeit exposing its internals everywhere, if you care about that).
  • dherman/dictjs if you live in an ES6 world.
  • es-lab's StringMap.js if you can deal with the lack of npm support.
  • es6-shim's Map if you want more than just strings for your keys.
  • Object.create(null) if you don't have to deal with V8 or JavaScriptCore, for which "__proto__" in Object.create(null) is still true.