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.