Object.getPrototypeOf


Historically one JavaScript property that’s seen a lot of use (mostly due to its convenience) is that of __proto__. It’s a quick-and-dirty way of accessing the original prototype property of the object’s constructor function. For example, the following is true:

  1. "test".__proto__ === String.prototype
  2.  
  3. // Another alternative, not using __proto__
  4. // Only works when constructor isn't changed
  5. "test".constructor.prototype === String.prototype

This feature has been codified in the upcoming ECMAScript 3.1 specification as a new method: Object.getPrototypeOf(object) (and is implemented in the latest Firefox nightlies).

So how can we make use of this, now standardized, functionality?

instanceOf

If you wish you could implement your own version of the instanceof operator, using pure JavaScript.

  1. function instanceOf(object, constructor) {
  2.   while (object != null) {
  3.     if (object == constructor.prototype)
  4.       return true;
  5.     object = Object.getPrototypeOf(object);
  6.   }
  7.   return false;
  8. }
  9.  
  10. instanceOf("test", String);
  11. instanceOf(true, Boolean);

In this example we traverse up the prototype chain, checking each constructor along the way. It’s an effective method and allows for great expressiveness in our code.

Super Methods

We could use this function to call a super method, while doing some inheritance.

  1. function Person(){}
  2.  
  3. Person.prototype.kick = function(type){
  4.   alert(type + " kick!");
  5. }
  6.  
  7. function Norris(){}
  8.  
  9. // Inherit properties from Person
  10. Norris.prototype = new Person();
  11.  
  12. Norris.prototype.kick = function(){
  13.   Object.getPrototypeOf(this).kick("Roundhouse");
  14. };

In the above code we use Object.getPrototypeOf(this) to tap in to the original, inherited, kick method. Since we have since overridden the method we don’t have direct access to it, but using getPrototypeOf we can capture, and utilize, it again.

Cross-Browser Implementation

The obvious question now becomes: How do we begin using Object.getPrototypeOf today if most browsers don’t have it implemented yet? In the meantime we can use something like the following code for some form of compatibility:

  1. if ( typeof Object.getPrototypeOf !== "function" ) {
  2.   if ( typeof "test".__proto__ === "object" ) {
  3.     Object.getPrototypeOf = function(object){
  4.       return object.__proto__;
  5.     };
  6.   } else {
  7.     Object.getPrototypeOf = function(object){
  8.       // May break if the constructor has been tampered with
  9.       return object.constructor.prototype;
  10.     };
  11.   }
  12. }

While it’s not 100% spot-on (since the .constructor property is mutable on any object – it’s fully possible that it could’ve been manipulated by the user at some point) the above code should serve as a “good enough” solution to tide you over until browsers have good ECMAScript 3.1 compatibility.

Why Object.getPrototypeOf?

A common question at this point (and one that’s sure to come up often as new features start to trickle in from ECMAScript 3.1): Why is the method Object.getPrototypeOf("test") and not "test".getPrototypeOf() – or even just a property, like __proto__? While having a method, or property, on every object would certainly be more convenient to use it ends up being impractical for generalized use.

For example, take the following case into consideration:

  1. var obj = { getPrototypeOf: "blah" };

Any attempt to call its getPrototypeOf method would end in failure, forcing the developer to always have to fall back to using the generalized Object.getPrototypeOf. Since most uses of getPrototypeOf would be required to work in the general case the fallback would always have to be used. Thus it’s not necessary to include it as an extra property of every object.

Additionally, it makes it far easier to backport to old implementations since you no longer have to extend the Object prototype (Object.prototype.getPrototypeOf = ...;) which would’ve been bad in any case.

Posted: August 14th, 2008


If you particularly enjoy my work, I appreciate donations given with Gittip.

17 Comments (Show Comments)



Comments are closed.
Comments are automatically turned off two weeks after the original post. If you have a question concerning the content of this post, please feel free to contact me.


Secrets of the JavaScript Ninja

Secrets of the JS Ninja

Secret techniques of top JavaScript programmers. Published by Manning.

Ukiyo-e Database and Search

Ukiyo-e.org

Japanese woodblock print database and search engine.


John Resig Twitter Updates

@jeresig

Infrequent, short, updates and links.


via Ad Packs