Isolating the Inheritance into a Function
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 prototype
property 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:
- Shape
- Triangle
- createPrototype (helper to get an empty object with defined prototype link)
In the linked example, there are 2 prototype objects:
- Shape.prototype (contains shared properties for shapes)
- Triangle.prototype (contains shared properties for triangles)
First a shape is created by calling new Shape()
. This creates a new object since new
is written in front of the function named Shape
. The prototype link of the object (__proto__
in Firefox) points to Shape.prototype
because 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 shape
the property is retrieved as follows. First, shape
is searched for the property. If it's there, use it. If not, the prototype object shape.__proto__
is retrieved which refers to the same object as Shape.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 the prototype
property of a constructor function (called createPrototype
in our case). After the empty prototype object with the prototype chain is created, it is instantly returned and assigned to Triangle.prototype
. After that any object created by new Triangle()
has the desired prototype chain.
Once this is set, we can add all shared properties of triangles into the Triangle.prototype
object that was just created. This is shown by overriding paint
and by adding getArea
. Note this overriding actually works because the paint
function for triangles is found earlier than the paint
method 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 shape
is shape
→Shape.prototype
and the one for triangle
is triangle
→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:
function makePrototype(parent){
// We need a new object whose prototype link points to parent.prototype
function createPrototype(){
}
createPrototype.prototype = parent.prototype;
return new createPrototype();
}
精彩评论