Object.create(null)

By  on  

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!

Recent Features

  • By
    CSS @supports

    Feature detection via JavaScript is a client side best practice and for all the right reasons, but unfortunately that same functionality hasn't been available within CSS.  What we end up doing is repeating the same properties multiple times with each browser prefix.  Yuck.  Another thing we...

  • By
    JavaScript Promise API

    While synchronous code is easier to follow and debug, async is generally better for performance and flexibility. Why "hold up the show" when you can trigger numerous requests at once and then handle them when each is ready?  Promises are becoming a big part of the JavaScript world...

Incredible Demos

  • By
    Introducing MooTools ElementSpy

    One part of MooTools I love is the ease of implementing events within classes. Just add Events to your Implements array and you can fire events anywhere you want -- these events are extremely helpful. ScrollSpy and many other popular MooTools plugins would...

  • By
    CSS 3D Folding Animation

    Google Plus provides loads of inspiration for front-end developers, especially when it comes to the CSS and JavaScript wonders they create. Last year I duplicated their incredible PhotoStack effect with both MooTools and pure CSS; this time I'm going to duplicate...

Discussion

  1. Steve

    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

  2. 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.

  3. Alex

    Bear in mind that you might have to iterate over objects created this way differently as they don’t have the hasOwnProperty method.

    • Orebakada

      I ran into this very issue as I was unaware that a module I was using (query-string) returned Object.create(null). My opinion is that Object.create(Object.freeze({})) should have been used instead.

  4. shadow

    funny thing, bumped into this in a douglas crockford talk:
    https://youtu.be/dkZFtimgAcM?t=19m10s

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!