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