JavaScript Ninja – Get Heritage Tree (Object-Oriented)

This Is Object-Oriented Related, Not Traversing The DOM-Tree *thing*..(N00b!)

function get_proto_tree(o, is_as_string){
  var tree, current;

  is_as_string = true === is_as_string;  //normalise undefined and other types to false, true kept true.
  if("object" !== typeof o) return [];

  tree    = [];
  current = o.__proto__ || Object.getPrototypeOf(current) || null; //normalise behavior

  if(null === current) return []; //unlikely since it should work for every object.

  while(null !== current){
    tree.push( current );
    current = current.__proto__ || Object.getPrototypeOf(current) || null; //normalise behavior
  }

  if(false === is_as_string) return tree;

  //return as array of srings instead of real-live objects.
  tree = tree.map(function(item){
    return item.toString().replace(/^\[object\ +/i,"").replace(/\]$/,"")
  });
  return tree;
}

You can test it with any object,
for example, window (like DOM’s window dude…)

get_proto_tree(window, /*is_as_string=*/true);

It should give you something like ["Window", "WindowProperties", "EventTarget", "Object"], which is pretty useful :)

But you might find it useful to use it in its default mode,
in that case you’ll get some live stuff back, not just strings,

If you are looking for an additional, further investigation,
for example to reverse-engineer a very dense object,
this may be extremely useful!


How it is best to be used for plain Chrome-extension/web-app development ?

say you want to add a .prototype = function.....,
that will be shared with both images (<IMG>) and scripts (<SCRIPT>).

run the following code:

function get_proto_tree(o, is_as_string){
  var tree, current;

  is_as_string = true === is_as_string;  //normalise undefined and other types to false, true kept true.
  if("object" !== typeof o) return [];

  tree    = [];
  current = o.__proto__ || Object.getPrototypeOf(current) || null; //normalise behavior

  if(null === current) return []; //unlikely since it should work for every object.

  while(null !== current){
    tree.push( current );
    current = current.__proto__ || Object.getPrototypeOf(current) || null; //normalise behavior
  }

  if(false === is_as_string) return tree;

  //return as array of srings instead of real-live objects.
  tree = tree.map(function(item){
    return item.toString().replace(/^\[object\ +/i,"").replace(/\]$/,"")
  });
  return tree;
}

//-----------------------------------------

var img    = document.querySelector("img")
   ,script = document.querySelector("script")
   ;

console.log(   get_proto_tree(img,    /*is_as_string=*/true)   );
console.log(   get_proto_tree(script, /*is_as_string=*/true)   );

the code above query one of the scripts and one of the images,
so you’ll have an instance of those objects,

it will return something like this:

["HTMLImageElement",  "HTMLElement", "Element", "Node", "EventTarget", "Object"]
["HTMLScriptElement", "HTMLElement", "Element", "Node", "EventTarget", "Object"]

You can easily spot that HTMLElement, is the nearest common-ancestor (not related to DOM-tree ancestry!)

And now you could use HTMLElement.prototype = function... to be shared with both of the image and script objects (and probably more…)

 

Hope it helps :)