Debunking object()
One of Crockford’s latest creations is the object() function, which he puts forth as a better way of doing prototypical inheritance in JavaScript. The function is as follows:
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
The basic idea is sound: you assign an object to be the prototype of a function, then instantiate that object, effectively creating a new object with the same properties and methods. Where the idea falls apart is when you consider creating multiple instances of an “inherited” object, for example:
var o = { colors : ['red', 'blue'] };
var o2 = object(o);
var o3 = object(o);
o2.colors.push('black');
alert(o2.colors);
alert(o3.colors);
If you run this example, you’ll see that the colors property actually uses the same array for both object instances, thus adding “black” to the array on o2 is reflected in o3.colors as well…they both point to the same array. It is a very rare case when you want object instances to have instance properties pointing to the same object.
But all is not lost, the basic principle of this function is useful if augmented slightly. Using this same pattern, you can avoid calling a superclass constructor when assigning the prototype. For instance, doing this:
Subclass.prototype = new Superclass();
This code ends up calling the constructor for Superclass just to get the prototype for inheritance of methods. But you can just grab a duplicate of the prototype instead using a function such as:
function inherit(subclass, superclass) {
function F() {};
F.prototype = superclass.prototype;
subclass.prototype = new F();
}
Use this function only to inherit prototypes, such as:
inherit(Subclass, Superclass);
You’ll still need to inherit properties via object masquerading in the Subclass constructor, but at least you won’t be executing the Superclass constructor twice anymore. What’s more, this function preserves the functionality of instanceof.
So, Crockford’s object() function is really nothing more than a function that clones another object. However, the technique can be used to ease prototypical inheritance in JavaScript as illustrated above.
Disclaimer: Any viewpoints and opinions expressed in this article are those of Nicholas C. Zakas and do not, in any way, reflect those of my employer, my colleagues, Wrox Publishing, O'Reilly Publishing, or anyone else. I speak only for myself, not for them.
Both comments and pings are currently closed.




5 Comments
I think that is essentially what YAHOO.extend (http://developer.yahoo.com/yui/docs/yahoo/YAHOO.html#extend) does.
Edited by admin
Dustin Diaz on October 17th, 2006 at 10:38 pm
Looks like you’re right, it does do that, along with some other stuff.
Nicholas C. Zakas on October 21st, 2006 at 8:33 pm
Nicholas,
(not that there was much to it). If you’re interested, I had it up on my blog: http://www.itsalleasy.com/2006/02/08/a-stab-at-javascript-inheritance/
I’m elated that this approach is getting some traction. I had the same idea about a year ago and couldn’t find anyone talking about or using it at all. I was shocked, honestly, because I felt it was the superior approach (most were simply using masquerading or SubClass.prototype = new SuperClass();). Funny, the Yahoo one looks remarkably similar
There were a few follow up posts with bug fixes and such.
James Estes on January 31st, 2007 at 3:03 pm
Actually, it makes sense that
o2.colors.push(‘black’);
affects o3.colors too- since they both reference the same object. If you wanted to just modify o2.colors, you’d need to set it explicitly- for example
o2.colors = ["red", "blue", "black"];
Doesn’t effect o3 at all
Greg Brown on July 5th, 2007 at 5:37 pm
@Greg – Yes, it makes sense because it’s the same object. My point is that, usually, that’s not what you want.
Nicholas C. Zakas on July 5th, 2007 at 10:21 pm
Comments are automatically closed after 14 days.