function Rectangle(width, height){
this.width = width;
this.height = height;
}
Rectangle.prototype.getArea = function(){
return this.width * this.height;
}
function Square(size){
this.width = size;
this.height= size;
}
// Square 继承 Rectangle
Square.prototype = new Rectangle();
Square.prototype.constructor = Square;
var square = new Square(5);
console.log(square instanceof Square); // true;
console.log(square instanceof Rectangle); // true
console.log(square.getArea());
为什么 Square
继承 Rectangle
时,不是用 Square.prototype
指向 Rectangle.prototype
,而是指向 Rectangle
的对象实例?(而实际上继承就是用 Square.prototype
指向 Rectangle.prototype
)。
如果:
那么对Square.prototype.getArea的修改就会影响到Rectangle.prototype.getArea;
就不会。
prototype实现继承的方式:
js中每个类都有prototype方法,他是一个原型链,如果本对象上找不到相关的方法,就会沿着这个原型链向父类,祖父类中找相关方法。
所以如果a类的prototype指向b类的实例,当a类中调用继承b类的方法的时候就会沿原型链找到b类对应的方法。
这个时候如果你把a类的prototype直接指向了b类的prototype,a类就找不到b类的方法,他去b类的父类找方法去了。
可以参考《JavaScript高级程序设计》 P.163页所描述的:继承是通过将SuperType的实例赋给SubType.prototype实现的。实现的本质是重写原型对象,代之以一个新类型的实例。换句话说,原来存在于SuperType的实例中的所有方法和属性,现在也存在于SubType.prototype中了。
在你给出的例子中,可以这样理解:
Square.prototype = new Rectangle() //重写Square的原型对象(如果你不指定它的原型对象,Square这个构造函数的原型对象就是Object)为Rectangle的实例,这时Square就继承了这个实例的属性和方法(这里只继承了属性)
,而getArea()这个方法是从Rectangle这个实例的原型中继承的。
如果使用 Square.prototype.constructor = Square; 那么Square.prototype就没有了 width/height 属性,Square对象也就继承不了width/height