monkeyPrototypes

This is currently working in Chrome (TODO: test IE), and my goal is to ask some simple questions about how objects really work in JavaScript. Follow along!

Make some mistakes

First, this is an empty object:

Now we can make children of it:

Now, can any primate eat?

What about just any animal?

So what is going on here? At least the dog can't eat a potato... Let us experiment some more.

How about we make the gibbon with new?

On the bright side, the dog can't brachiate or make the angry gorilla face, but this code, too, may not be behaving as we want... In real life, only gibbons and siamangs truly brachiate, although humans and monkeys and orangutangs have most of the right parts. It is strange that we never play on gibbon bars. They can go 35 mph.

Now, how are the furry animals?

Hmmm...

Thanks to the little create() method, this is behaving much better. Cats don't all play(), and they hunt differently, but housecats sleep() the same way all cats do. They make humans jealous.

Let us clarify about housecats, though...

How about that prototype?

The second question errors out! Why?

The inherited tail behavior is cool, though...

Constructors

Now lets learn some more! Following Resig's new book, online...

That test for hunger really is pretty cheap. (No biting necessary.) Can all arthropods get hungry?

So what do the prototypes built here look like to the browser? Functions have a toString method...

So, to show the properties of the prototypes:

Some thoughts

It seems that the constructor functions and the new keyword provide a way to distinguish between object constructors, which have accessible prototypes (because they are functions) and object instances.

Both instances and new constructors are created with new and ancestral constructor functions. As above:

...

// a new instance
var aSpider = new MakeAnArthropod();

...

// a new constructor
var MakeACentipede = function () {};
MakeACentipede.prototype = new MakeAnArthropod();

...
            

Resig, by the way, suggests a mechanism to make a constructor that doesn't require new to be used to call it. It uses instanceof like so:

var Constructor = function (...) {
    if (!(this instanceof arguments.callee)) {
        return new Constructor(...)
    }
    ...
}

He also mentions constructor, chaining and a bunch of other interesting things I'm working my way through now...

Regardless, what I've done above seems a bit artificial. Can't I make a constructor out of nearly anything and employ prototypal inheritance?

And how did that snippet from Crockford really work? Crockford suggests adding that create() method to Object and then never using new again. Here it is again:

// snazzy stuff from Crockford that makes a create() method
if (typeof Object.create !== 'function') {
   Object.create = function (o) {
       var F = function () {};
       F.prototype = o;
       return new F();
   };
}

var housecat = Object.create(cat);
        

First, create is defined as a method of Object (this doesn't seem necessary). Second, within this method, a constructor F is defined and its prototype set to the argument, o. Finally, the new constructor is called with new to make the desired descendant object.

This seems like a nice way to wrap the creation of an object with a prototype ancestry in a normal method or function. It might be better, though, to leave Object alone. The next thing to try is to set up some more functional and durable constructors as Crockford's book suggests...

(For something different, Coffee Script has class and extends keywords in a way that seems to make everything more explicit. This tutorial has a section describing it.)

(Also, the way Ruby does some of this stuff seems rather mindbending at first glance.)

Evolution!

To return to our theme, lets start with our old primate buddy. He was based on an empty object, {}, and has some properties that may or may not make sense, but he exists. (He's printed below using document.write(printObj("primate", primate)), actually...)

We need some tools to work with.

Now, progress a few million years like so:

This is easy to reason about. Each primate or homo or erectus is simply an example of a species of one of our ancestors. Although they are each instances, the can still have descendants!

Telling, I suppose, that Neandertal never really had the big civilization thing going. The best explanations I've seen for that are either self referential (i.e., they didn't have a gene for civilization so they didn't survive long enough to make civilization) or immunological (i.e. some germ took them out). But we do seem to have picked up some things from them.

Now about our best friends... We defined some things above that we can still use. Especially without proper training.