JS继承之原型继承

在继承时,出于效率的考虑,我们会尽可能地将一些可重用的属性和方法添加到原型中去,如果如此,我们就可以仅依靠原型就完成继承关系的构建。

function Shape() {} 
Shape.prototype.name = 'shape'; 
Shape.prototype.toString = function() {return this.name;};

function TwoDShape() {}
TwoDShape.prototype = Shape.prototype;
TwoDShape.prototype.constructor = TwoDShape;
TwoDShape.prototype.name = '2D shape'; 

function Triangle(side,height) {                                                                                                                                  
  this.side = side;                                                                                                                                      
  this.height = height;                                                                         
}                                                                                                    
Triangle.prototype = TwoDShape.prototype;    
Triangle.prototype.constructor = Triangle;
Triangle.prototype.name = 'Triangle'; 
Triangle.prototype.getArea = function() {return this.side*this.height/2;}     

var a = new Triangle(2,10);
a.toString();      //"Triangle"

这样写,只继承于原型,执行a.toString()时,JavaScript引擎会先查看a对象中有没有toString()方法,找不到就会去搜索该对象的原型属性,此时该原型已经指向了TwoDShape的原型,而后者指向的又是Shape.prototype,且这里采用的是引用传递,因此就能精简查询步骤。

但它存在着副作用,由于子对象与父对象指向的是同一个对象,所以一旦子对象对其原型进行修改,父对象也会随着被改变,甚至所有的继承关系也是如此。因此,我们可以通过利用一个临时构造器来打破这种连锁关系,即创建一个空函数f(),并将其原型设置为父级构造器。然后,我们既可以用new F()来创建一些不包含父对象属性的对象,同时又可以从父对象prototype属性中继承一切。

function TwoDShape() {}
//----------临时构造器----------
var F = function() {};
F.prototype = Shape.prototype;
TwoDShape.prototype = new F();
TwoDShape.prototype.constructor = TwoDShape;
TwoDShape.prototype.name = '2D shape'; 


function Triangle(side,height) {                                                                                                                                  
  this.side = side;                                                                                                                                      
  this.height = height;                                                                         
} 
//----------临时构造器----------
var F = function() {};      
F.prototype = Shape.prototype;                                                                                             
Triangle.prototype = new F();   
Triangle.prototype.constructor = Triangle;
Triangle.prototype.name = 'Triangle'; 
Triangle.prototype.getArea = function() {return this.side*this.height/2;}    

基于此,我们可以将这些实现继承关系的代码封装起来

function extend(Child, Parent) {
  var F = function() {};
  F.prototype = Parent.prototype;
  Child.prototype = new F();
  Child.prototype.constructor = Child;
}

猜你喜欢

转载自blog.csdn.net/qq_32682137/article/details/82426843
今日推荐