Click here to Skip to main content
15,881,852 members
Articles / Programming Languages / Javascript

Safely Navigating Object Hierarchies in JavaScript using Prototype Methods

Rate me:
Please Sign up or sign in to vote.
4.00/5 (3 votes)
14 Aug 2017CPOL1 min read 5.8K   3
How to safely navigate object hierarchies in JavaScript using Prototype methods

Anyone who’s dealt with a deeply nested set of properties in JavaScript, whether through use of an extensive third-party JavaScript API or a custom library, has likely run into the problem of safely accessing such structures. One can of course hand-roll many ugly, hard-to-read statements like the following, adding on to the maintenance burden of the code (splitting lines as necessary for length, of course):

JavaScript
if (a && a.b && a.b.c && a.b.c.d && a.b.c.d.e) { doSomethingWith(a.b.c.d.e); }

The main alternative to this approach is to make such accesses within a try-catch block, but this is generally slower by at least a couple of orders of magnitude when exceptions are thrown, so not always useful in tight loops and other performance-sensitive situations. It’s also arguably an abuse of the try/catch mechanism.

Luckily, a less unsavory solution with fairly good performance can be adopted using JavaScript prototype methods. Here’s a reference implementation, and you can also try it for yourself (with timings):

JavaScript
// Indicates whether an object has the indicated nested subproperty, 
// which may be specified with chained dot notation 
// or as separate string arguments.
Object.prototype.hasSubproperty = function() {
	if (arguments.length == 0 || typeof(arguments[0]) != 'string') return false;  
  var properties = arguments[0].indexOf('.') > -1 ? arguments[0].split('.') : arguments;    
  var current = this;
  for(var x = 0; x  -1 ? arguments[0].split('.') : arguments;    
  var current = this;
  for(var x = 0; x < properties.length; x++) {
  	current = current[properties[x]];
    if ((typeof current) == 'undefined') return undefined;
  }  
  return current;
};

// Gets the indicated nested subproperty, which may be specified with chained dot notation 
// or as separate arguments.
// If the specified subproperty (or any intervening object in the hierarchy) is not found, 
// returns undefined.
Object.prototype.getSubproperty = function() {
	if (arguments.length == 0 || typeof(arguments[0]) != 'string') return false;  
  var properties = arguments[0].indexOf('.') > -1 ? arguments[0].split('.') : arguments;    
  var current = this;
  for(var x = 0; x < properties.length; x++) {
  	current = current[properties[x]];
    if ((typeof current) == 'undefined') return undefined;
  }  
  return current;
};

// Sets the indicated nested subproperty, which may be specified with chained dot notation 
// or as separate arguments.
// If any intervening object in the hierarchy is not found, returns false, 
// otherwise sets the value and returns true.
Object.prototype.setSubproperty = function() {
	if (arguments.length  -1 ? arguments[0].split('.') : 
          Array.prototype.slice.call(arguments, 0, arguments.length - 1);    
  var parent, current = this;
  for(var x = 0; x < properties.length - 1; x++) {
  	current = current[properties[x]];
    if ((typeof current) == 'undefined') return false;
  }  
  current[properties[properties.length - 1]] = arguments[arguments.length - 1];
  return true;
};

Some observations: If you run the timings, you’ll note that the try-catch method is still quite fast when exceptions are not thrown, indicating that try-catch might be workable when exceptions are expected to be truly… exceptional. Still, in any but extraordinary conditions, the performance of the prototype-method approach should be quite fast enough, avoids worst-case performance, and is cleanest overall.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralFew observations Pin
Booster2ooo19-Aug-17 22:38
Booster2ooo19-Aug-17 22:38 
GeneralRe: Few observations Pin
Jeff Varszegi22-Aug-17 1:33
professionalJeff Varszegi22-Aug-17 1:33 
GeneralRe: Few observations Pin
Booster2ooo25-Aug-17 23:57
Booster2ooo25-Aug-17 23:57 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.