Get and Set Nested Objects with JavaScript
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!
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
lodash has this, it’s
_.set(obj, 'a.b.c', 'new value')
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.