We'll respond shortly.
For the sake of examples consider the following class hierarchy: Athlete, Footballer, and Defender.
Implementing this with pseudo-classical inheritance would look something like this, assuming the implementation of
Object.extend() from here (I’ve had bad luck with the __super attribute in the past, but let’s assume it works for the moment).
This creates relationships between constructor functions and prototypes that look something like this (if you’ll excuse the ASCII art):
Object.prototype ^ | Athlete() ----> Athlete.prototype ^ | Footballer() ----> Footballer.prototype ^ | Defender() ----> Defender.prototype
prototype attributes. Creating a new instance
defender of the Defender class creates these relationships between the prototoypes and the instance:
Object.prototype ^ | Athlete.prototype ^ | Footballer.prototype ^ | defender ----> Defender.prototype
This should look familiar; it’s exactly the pattern that Ruby uses for basic inheritance, with the prototype objects representing instances of Ruby’s Class object, and prototype attributes representing Ruby’s
Object#class (horizontal) or
Class#superclass (vertical) attributes. The lookup rules work the same as Ruby as well: start with methods on the instance (in Ruby these would be methods on the instance’s singleton class); if not found, look for a method on the instance’s class; if not found, look on the Class instance’s superclass; repeat until found or you run out of classes/prototypes.
self; public instance methods next, ending with the return of self; private instance methods at the end, where they belong.
I’ve heard brought up a couple concerns with this style:
anymethod) depend on this.
We’ve recently finished up a reasonably sized project largely using this functional style of object definition, and it worked quite well. I’m sure there’s some reason that it shouldn’t have that I’ve overlooked; I’m curious to hear what that is.