http://jsbin.com/ifoguf/14/edit#javascript
I attempted Isolating the Inheritance Part into a Function, but when I create the object nothings is alerted, no errors are returned, so I’m stumped how to debug, and for a solution.
function Shape(){}
// augment prototype
Shape.prototype.name = 'shape';
Shape.prototype.toString = function() {return this.name;};
function TwoDShape(){}
// augment prototype
TwoDShape.prototype.name = '2D shape';
function Triangle(side, height) {
this.side = side;
this.height = height;
}
// augment prototype
Triangle.prototype.name = 'Triangle';
Triangle.prototype.getArea = function(){return this.side * this.height / 2;};
var myTriangle = new Triangle(5, 10);
function extend(Child, Parent) {
var F = function(){};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype;
}
extend(TwoDShape, Shape);
extend(Triangle, TwoDShape);
var myTriangle = new Triangle(5, 10);
alert(myTriangle.getArea());
alert(myTriangle.toString());
var s = new Shape();
alert(s.name);
TIA
Your code seemed a bit complex. See a simpler example (remember to switch on a debugging tool to see log messages).
It’s worth noting that inheritance in JavaScript works by following prototype chains. That means every object holds a reference to a prototype object. This prototype object is just any ordinary object, too. The key is is that whenever a property (or function) is not found within an object, its prototype object is checked. This follows the prototype links until either a value was found or no prototypes are left over.
The prototype link is stored within an object whenever an object is created and points to the object as specified in the
prototypeproperty of the object’s constructor function. You can inspect the prototype in Firefox by checking an object’s__proto__property.In the linked example, there are 3 constructors:
In the linked example, there are 2 prototype objects:
First a shape is created by calling
new Shape(). This creates a new object sincenewis written in front of the function namedShape. The prototype link of the object (__proto__in Firefox) points toShape.prototypebecause this property of the constructor function gives the prototype link’s target. The link is set on object instantiation.As a result whenever you try to access a property of the
shapethe property is retrieved as follows. First,shapeis searched for the property. If it’s there, use it. If not, the prototype objectshape.__proto__is retrieved which refers to the same object asShape.prototype. Now, the prototype object is searched for the property.For the case of triangle the thing is a bit more complex because multiple prototype links are involved. The important thing is that we need to create an empty object to hold the triangles’ shared properties which also needs to have its prototype link set to point to
Shape.prototype. This makes shape’s prototype the fallback of triangle’s prototype.It is archived by the anonymous function that includes
createPrototype. It needs to be included because every invocation of the anonymous function needs to manipulate theprototypeproperty of a constructor function (calledcreatePrototypein our case). After the empty prototype object with the prototype chain is created, it is instantly returned and assigned toTriangle.prototype. After that any object created bynew Triangle()has the desired prototype chain.Once this is set, we can add all shared properties of triangles into the
Triangle.prototypeobject that was just created. This is shown by overridingpaintand by addinggetArea. Note this overriding actually works because thepaintfunction for triangles is found earlier than thepaintmethod for shapes and the first found reference/property is used.To summarize, all property accesses on objects use prototype chains for fallbacks. In our case the chain for
shapeisshape→Shape.prototypeand the one fortriangleistriangle→Triangle.prototype→Shape.prototype.You might want to assign a name to the anonymous function (that includes
createPrototype) to have a tool for created object hierarchies. This is shown in the updated example and ends up with the following helper: