Object.create(null)
One of the funnest parts of JavaScript, or any programming language really, is that there are loads of tiny tricks and quirks that make the language that much more interesting. I recently learned a nice fact about Object.create
: using null
as the only argument to create an ultra-vanilla dictionary!
Object.create
has been an awesome utility for prototype creation. While that's nice, objects created with Object.create
have __proto__
and inherited Object
properties which can be manipulated. What if you simply want a dictionary not prone to manipulation from the outside? You can have that with Object.create(null)
:
let dict = Object.create(null); // dict.__proto__ === "undefined" // No object properties exist until you add them
Since there's no prototype your Object can't be manipulated from the outside -- it remains as vanilla of a dictionary as possible! Compare that to Object.create({})
:
let obj = Object.create({}); // obj.__proto__ === {} // obj.hasOwnProperty === function Object.prototype.someFunction = () => {}; // obj.someFunction === () => {}; // dict.someFunction === undefined
Passing Object.create
an empty object allows for properties to be added via Object.prototype.customPropName
, something you may not always want.
I hadn't known of this trick until recently but will be using it quite a bit going forward!
Great article David. Thanks for taking tge time to write it. You may already be aware, but you can also use
Map
for this. And it comes with some advantages over using a plain object. For example you have functions that allows you to check if an item exists with a specified key, remove all items, etc. Additionally keys themselves can be of any type, with a plain object you can’t use objects as keys.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
That’s cool but what about the next guy who works on an object created by that? This would, more often than not, be a case where an object would have unexpected behavior.
Bear in mind that you might have to iterate over objects created this way differently as they don’t have the
hasOwnProperty
method.I ran into this very issue as I was unaware that a module I was using (
query-string
) returnedObject.create(null)
. My opinion is thatObject.create(Object.freeze({}))
should have been used instead.funny thing, bumped into this in a douglas crockford talk:
https://youtu.be/dkZFtimgAcM?t=19m10s