In javascript, is there a syntax shortcut checking for the existence of each layer of an inline object?

for example the following code

  if (obj.attr1.attr2.attr3.attr4 == 'constant') return;

need to rewrite how

  if (obj.attr1 
       && obj.attr1.attr2 
       && obj.attr1.attr2.attr3
       && obj.attr1.attr2.attr3.attr4 == 'constant') return;

I correctly understood that each level needs to be tested individually or is there a syntax shortcut for this?

if it was a single shot, it would not be a problem, but this construct permeates my code.



from the answers, here is the solution I have in place:

  try {if (obj.attr1.attr2.attr3.attr4! = 'const') throw 'nada';  } catch (e) {
     nonblockAlert ('Relevant Message');
     return
 };

this works because the error caused by the absence of attr breaks with local throw (). the problem is that the syntax does not fit into the will with normal, if then another control.

+1
source share
5 answers

As already mentioned, but no one has done this, you can use try / catch:

try { if(obj.attr1.attr2.attr3.attr4 == 'constant') return; } catch(e) {} 

This is not the best code, but it is the most concise and easy to read. The best way to avoid this would be to not have such a deeply nested tree of possibly missing objects.

+2
source

no real shortcut. You can write a helper function to do this for you, which may condense:

 function getProp(obj){ var i=0, l=arguments.length; while(i<l && (obj = obj[arguments[i++]])); return obj; } if( getProp(obj, 'attr1', 'attr2', 'attr3', 'attr4') == 'constant') 

or you can do:

 var tmp; if((tmp = obj.attr1) && (tmp=tmp.attr2) && (tmp=tmp.attr3) && (tmp.attr4 == 'constant')) { 
+3
source

An interesting question - although I never had a problem. The best alternative I can think of is to write a helper function:

 function get(chain, context) { var o = arguments.length == 2 ? context : window, c = chain.split('.'); for (var i = 0; i < c.length; i++) { if (!o) return null; o = o[c[i]]; } return o; } 

If obj is global, you can do something like:

 if (get('obj.attr1.attr2.attr3.attr4') == 'constant') return; 

Otherwise:

 if (get('attr1.attr2.attr3.attr4', obj) == 'constant') return; 
+2
source

No, unfortunately not, if you do not use try/catch . You could, however, write yourself an auxiliary function (untested, but there is a concept):

 function existsAndEquals(obj, layers, compare) { for (var i = 0; i < layers.length; i++) if (!(obj = obj[layers[i]])) return false; return obj == compare; } if (existsAndEquals(obj, ['attr1', 'attr2', 'attr3', 'attr4'], 'constant')) // ... 
0
source

You can use a call (or apply) to change the context of evaluating a row from a window to any object

 function getThis(string){ var N= string.split('.'), O= this[N.shift()]; while(O && N.length) O= O[N.shift()]; return O; } window.obj={ attr1:{ attr2:{ attr3:{ attr4: 'constant!' } } } } 

<strong> getThis ('obj.attr1.attr2.attr3.attr4');

/ * return value: (String) ' constant! '* /

getThis.call (obj, 'attr1.attr2.attr3.attr4');

/ * return value: (String) ' constant! '* /

0
source

All Articles