上一讲我们学会了通过原型来继承父类实例的属性,即用prototype指向一个父类实例。
这样做我们需要人为地实例化一个父类对象,而且如果父类中有一些特别的属性和行为子类有可能是用不到。
由此我们自然会想,有没有一种办法只将一些公共属性和行为公开,让子类来继承呢?
做法很简单,就是将这些公共的属性和行为全部定义到父类的prototype中。
function Shape(){ } Shape.prototype.name = 'shape'; Shape.prototype.toString = function() {return this.name;};
有一个2d形状的类,只需复用Shape的prototype(也是一个对象)的属性,就可以这样做
function TwoDShape(){ } //先继承 TwoDShape.prototype = Shape.prototype;//与之前不同 TwoDShape.prototype.constructor = TwoDShape; //重写 TwoDShape.prototype.name = '2D shape';
同理,三角形Triangle是一种典型的2d形状,它可以有自己的属性和行为,同时又需要继承TwoDShape的属性:
function Triangle(side, height) { this.side = side; this.height = height; this.getArea = function(){return this.side * this.height / 2;}; } Triangle.prototype = TwoDShape.prototype; Triangle.prototype.constructor = Triangle; //重写 Triangle.prototype.name="Triangle";
测试一下效果:
var my = new Triangle(5, 10); /**/ alert(my.getArea()); alert(my.toString());//自己没有toString方法,继承而来 alert(my.constructor); alert(my instanceof TwoDShape);//有继承的特性 alert(my instanceof Shape);
但是问题也出现了:
var shape = new Shape(); alert(shape.name);//坏了,重写变成了改写。。。
打印shape.name弹出的是Triangle
这是因为Triangle.prototype TwoDShape.prototype Shape.prototype指向的都是同一个对象,使用前最后一次修改决定了使用时的状态。
既然我们想到了用prototype来封装共性的供子类复用的属性和行为,那么我们可以坚持这种做法,但是目前这种写法带来的问题又该如何解决呢?请看下回分解!!
时间: 2024-10-07 05:51:02