test the existence of property in a deep object structure

前端 未结 6 1339
悲&欢浪女
悲&欢浪女 2021-01-11 23:13

In javascript, lets say I want to access a property deep in an object, for example:

entry.mediaGroup[0].contents[0].url

At any point along that structure, a

6条回答
  •  醉酒成梦
    2021-01-12 00:09

    Your current solution is probably as good as you can get, as mVChr says, try..catch is just lazy here. It's probably far less effient and has nothing to recommend it other than perhaps being easier to type (but not significantly so) and it'll be harder to debug as it silently hides errors.

    The real issue is the very long "reference worm" created by attempting such access. An alternative to the original that at least reduces the number of property lookups is:

    var o;
    if ( (o = entry       ) &&
         (o = o.mediaGroup) &&
         (o = o[0]        ) &&
         (o = o.contents  ) &&
         (o = o[0]        )) {
      alert(o.url);
    }
    

    But I expect you won't like that.

    If you have many such deep access paths, you might like to create a function to do the access and return the last object on success or some other vaule on failure. For failure, you could also have it return the last non-falsey object on the path.

    // Create test object
    var entry = {};
    entry.mediaGroup = [{
      contents: [{url: 'url'}]
    }];
    
    // Check that it "works" 
    // alert(entry.mediaGroup[0].contents[0].url);
    
    
    // Deep property access function, returns last object
    // or false
    function deepAccess(obj) {
    
      var path = arguments;
      var i = 0, iLen = path.length;
      var o = path[i++];  // o is first arg
      var p = path[i++];  // p is second arg
    
      // Go along path until o[p] is falsey
      while (o[p]) {
        o = o[p];
        p = path[i++];
      }
    
      // Return false if didn't get all the way along
      // the path or the last non-falsey value referenced
      return (--i == iLen) && o;
    }
    
    // Test it    
    var x = deepAccess(entry, 'mediaGroup','0','contents','0');
    alert(x && x.url);  // url
    
    var x = deepAccess(entry, 'mediaGroup','1','contents','0');
    alert(x && x.url);  // false
    

提交回复
热议问题