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
    Animated 3D Flipping Menu with CSS

    CSS animations aren't just for basic fades or sliding elements anymore -- CSS animations are capable of much more.  I've showed you how you can create an exploding logo (applied with JavaScript, but all animation is CSS), an animated Photo Stack, a sweet...

  • 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
    MooTools Clipboard Plugin

    The ability to place content into a user's clipboard can be extremely convenient for the user. Instead of clicking and dragging down what could be a lengthy document, the user can copy the contents of a specific area by a single click of a mouse.

  • By
    jQuery Comment Preview

    I released a MooTools comment preview script yesterday and got numerous requests for a jQuery version. Ask and you shall receive! I'll use the exact same CSS and HTML as yesterday. The XHTML The CSS The jQuery JavaScript On the keypress and blur events, we validate and...

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!