Get and Set Nested Objects with JavaScript

By  on  

Back when JavaScript frameworks like MooTools and jQuery ruled the land we all wrote tutorials which were framed more toward the given framework instead of vanilla JavaScript.  Sad but true.  These days I avoid framework-oriented posts since Node.js has taken over the world and JavaScript toolkits come and go.

One very useful post I wrote and still love is Create and Retrieve Nested Objects with MooTools.  In that post I showed you how you can easily get and set nested objects, since doing existence checks down the object chain in a manual way is ... ugly.  Let's tear this functionality out of its MooTools orientation so you can take it with you wherever you go!

The JavaScript

We'll use a simple immediately-executing function to wrap the underlying "worker" function and return an object with properties for getting, setting, and checking existence:

var Objectifier = (function() {

	// Utility method to get and set objects that may or may not exist
	var objectifier = function(splits, create, context) {
		var result = context || window;
		for(var i = 0, s; result && (s = splits[i]); i++) {
			result = (s in result ? result[s] : (create ? result[s] = {} : undefined));
		}
		return result;
	};

	return {
		// Creates an object if it doesn't already exist
		set: function(name, value, context) {
			var splits = name.split('.'), s = splits.pop(), result = objectifier(splits, true, context);
			return result && s ? (result[s] = value) : undefined;
		},
		get: function(name, create, context) {
			return objectifier(name.split('.'), create, context);
		},
		exists: function(name, context) {
			return this.get(name, false, context) !== undefined;
		}
	};

})();

So how would you use this set of functions?  Here are some sample usage examples:

// Creates my.namespace.MyClass
Objectifier.set('my.namespace.MyClass', {
	name: 'David'
});
// my.namespace.MyClass.name = 'David'

// Creates some.existing.objecto.my.namespace.MyClass
Objectifier.set('my.namespace.MyClass', {
	name: 'David'
}, some.existing.objecto); // Has to be an existing object

// Get an object
Objectifier.get('my.namespace.MyClassToo');

// Try to find an object, create it if it doesn't exist
Objectifier.get('my.namespace.MyClassThree', true);

// Check for existence
Objectifier.exists('my.namespace.MyClassToo'); // returns TRUE or FALSE

Notice I didn't extend the Object prototype; you could but we've moved on from that practice.

I use these functions on just about every project I work on.  I find them very useful when dealing with APIs, as you can never assume an object chain exists.  I wish I had included this code within my 7 Essential JavaScript Functions post!

Recent Features

  • By
    5 Ways that CSS and JavaScript Interact That You May Not Know About

    CSS and JavaScript:  the lines seemingly get blurred by each browser release.  They have always done a very different job but in the end they are both front-end technologies so they need do need to work closely.  We have our .js files and our .css, but...

  • By
    Responsive and Infinitely Scalable JS Animations

    Back in late 2012 it was not easy to find open source projects using requestAnimationFrame() - this is the hook that allows Javascript code to synchronize with a web browser's native paint loop. Animations using this method can run at 60 fps and deliver fantastic...

Incredible Demos

  • By
    PHP / MooTools 1.2 Accordion Helper

    The MooTools Accordion plugin seems to be the plugin that people seem to have the most problems with. It's an awesome plugin, so I can see why so many people want to use it, but I think that may be part of the problem.

  • By
    Ana Tudor’s Favorite CodePen Demos

    Cocoon I love canvas, I love interactive demos and I don't think I have ever been more impressed by somebody's work than when I discovered what Tiffany Rayside has created on CodePen. So I had to start off with one of her interactive canvas pens, even though...

Discussion

  1. Rick

    I’ve recently published a PHP Class that does much the same thing but in PHP (with a few extra magic functions) and designed for nested arrays and objects…

    Nest

    $nest = new Nest\Nest();
    $nest->foo__bar = "baz";
    var_dump($nest->doesnt__exist); // null
    var_dump($nest->doesnt__exist("my default")); // "my default"
    
  2. voon ming hann

    lodash has this, it’s _.set(obj, 'a.b.c', 'new value')

  3. Bill

    I can’t get this to work, the “exists” part always returns false for me, even though I’ve double checked everything is correct in my code. Are you sure this function works as you describe? In particular checking if an object exists? I would like to use it, but not if it’s broken.

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