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

Incredible Demos

  • By
    iPhone Checkboxes Using MooTools

    One of the sweet user interface enhancements provided by Apple's iPhone is their checkbox-slider functionality. Thomas Reynolds recently released a jQuery plugin that allows you to make your checkboxes look like iPhone sliders. Here's how to implement that functionality using the beloved...

  • By
    Resize an Image Using Canvas, Drag and Drop and the File API

    Recently I was asked to create a user interface that allows someone to upload an image to a server (among other things) so that it could be used in the various web sites my company provides to its clients. Normally this would be an easy task—create a...

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!