881

If I have a reference to an object:

var test = {}; 

that will potentially (but not immediately) have nested objects, something like:

{level1: {level2: {level3: "level3"}}}; 

What is the best way to check for the existence of property in deeply nested objects?

alert(test.level1); yields undefined, but alert(test.level1.level2.level3); fails.

I’m currently doing something like this:

if(test.level1 && test.level1.level2 && test.level1.level2.level3) { alert(test.level1.level2.level3); } 

but I was wondering if there’s a better way.

9
  • 1
    you might want to check a tangentially related question that was asked recently stackoverflow.com/questions/2525943/… Commented Apr 13, 2010 at 16:21
  • See also stackoverflow.com/questions/10918488/… Commented Dec 21, 2012 at 15:38
  • A couple of propositions there : stackoverflow.com/a/18381564/1636522 Commented Sep 7, 2013 at 7:27
  • Your current approach has a potential issue if level3 property is a false, in that case, even if the property exist will retur nfalse have a look at this example please jsfiddle.net/maz9bLjx Commented Jul 11, 2015 at 6:18
  • 13
    simply you can use try catch also Commented Aug 12, 2015 at 12:07

64 Answers 64

1 2
3
-1
/** * @method getValue * @description simplifies checking for existance and getting a deeply nested value within a ceratin context * @argument {string} s string representation of the full path to the requested property * @argument {object} context optional - the context to check defaults to window * @returns the value if valid and set, returns undefined if invalid / not available etc. */ var getValue = function( s, context ){ var fn = function(){ try{ return eval(s); }catch(e){ return undefined; } } return fn.call(context||window,s); } 

and usage :

if( getValue('a[0].b[0].b[0].d') == 2 ) // true 
Sign up to request clarification or add additional context in comments.

Comments

-2

I automated the process

if(isset(object,["prop1","prop2"])){ // YES! } function isset(object, props){ var dump; try { for(var x in props){ if(x == 0) { dump = object[props[x]]; return; } dump = dump[props[x]]; } } catch(e) { return false; } return true; } 

3 Comments

A couple things to note. You're doing a for/in over an array, which is not recommended. That is really meant for objects. There's no guarantee that the order of execution will be consistent. Also, if you're going to loop over the properties, I probably wouldn't use try/catch. I think you'll get better performance taking a if( props[x] in object ) approach, or if( object.hasOwnProperty(props[x]) ) if you don't want to include prototype properties. My situation was such that I was only interested in the deepest property. That's why I chose try/catch.
If you look closely, I move in the object level using the dump variable, I am not staying at level 1
but your right about for/in, my heart is broken :/, it is also slower
-4

Just wrote this function today which does a deep search for a property in a nested object and returns the value at the property if found.

/** * Performs a deep search looking for the existence of a property in a * nested object. Supports namespaced search: Passing a string with * a parent sub-object where the property key may exist speeds up * search, for instance: Say you have a nested object and you know for * certain the property/literal you're looking for is within a certain * sub-object, you can speed the search up by passing "level2Obj.targetProp" * @param {object} obj Object to search * @param {object} key Key to search for * @return {*} Returns the value (if any) located at the key */ var getPropByKey = function( obj, key ) { var ret = false, ns = key.split("."), args = arguments, alen = args.length; // Search starting with provided namespace if ( ns.length > 1 ) { obj = (libName).getPropByKey( obj, ns[0] ); key = ns[1]; } // Look for a property in the object if ( key in obj ) { return obj[key]; } else { for ( var o in obj ) { if ( (libName).isPlainObject( obj[o] ) ) { ret = (libName).getPropByKey( obj[o], key ); if ( ret === 0 || ret === undefined || ret ) { return ret; } } } } return false; } 

1 Comment

i think question is about verifying the existence of property not search it out in any one of the children of the object which is different. a.b.c and a.e.c will both return value if urfunc(a,'c') is called. function like if(exists(a.b.c)) is ideal
-4

In typeScript you can do something like this:

 if (object.prop1 && object.prop1.prop2 && object.prop1.prop2.prop3) { const items = object.prop1.prop2.prop3 console.log(items); } 

1 Comment

So... exactly the same as in JavaScript mentioned in the question?
1 2
3

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.