javascript原型继承

关于javascriptz中的‘类’,能够总计为3个部分:javascript

1.构造函数内的,这是供实例化对象复制用的;java

2.构造函数外的,直接经过点语法添加的,这是供类使用的,实例化的对象是访问不到的;函数

3.类原型中的,实例化对象能够经过原型链间接的访问到,也是供实例对象所共有的。this

关于类的继承大体能够分为如下几种。spa

1、子类的原型对象--类式继承prototype

  思路:将父类的实例化对象做为子类的prototype3d

// 子类的原型对象 -- 类式继承
// 声明父类
function SuperClass(){
    this.superValue = true;
    this.books = [1,2,3];
}
SuperClass.prototype.getSuperValue = function(){
    return this.superValue
}
// 声明子类
function SubClass(){
    this.subValue = false;
}
// 继承父类
SubClass.prototype = new SuperClass();  //{superValue:true,books:[1,2,3]}
// 
SubClass.prototype.getSubValue = function(){
    return this.subValue;
}

此类继承是最简单的继承方法,可是也有缺点。code

1.因为子类经过原型prototype对父类实例化,继承了父类,因此父类中的共有属性若是是引用类型,就会在子类的全部实例中共有,若是一个子类的实例修改子类的原型从父类继承来的共有属性就会影响到其余的子类。对象

var i1 = new SubClass();
var i2 = new SubClass();
i1.books === i2.books   // true  由于都是经过原型链找到的 SubClass.prototype 这个对象
i1.books.push(4);
console.log(i2.books);  // [1,2,3,4]
i1实例修改了books属性,i2的books属性也会被影响

2.因为子类实现的继承是靠原型prototype对父类实例化实现的,所以在建立父类的时候没法向父类传递参数的。所以在实例化子类实例的时候,没法定制父类中的属性(也就是全部的子类实例共用同一个父类的实例,即继承时传递的参数或者父类构造函数中默认的)blog

2、建立即继承--构造函数继承

  思路:在子类构造器内 调用父类构造器

// 声明父类
function SuperClass(id){
    this.books = [1,2,3];
    this.id = id;
}
// 声明子类
function SubClass(id){
    // 继承父类
    SuperClass.call(this,id)
    // ...
}

该类型的继承即经过在子类的构造器中经过call调用父类的构造函数,来改变this的指向,达到继承父类构造函数共有属性。

优势:

  每个子类的实例,能够经过传入id来指定当前实例的id属性值,实现了属性的私有化;

缺点:

  1.这种继承并无涉及原型,因此父类原型上的方法和属性不会被继承;

  2.要被继承的方法和属性只能放在父类的构造函数中,可是建立出来的每一个实例都单独含有一份,不能实现共有,违背了代码复用的原则。

3、组合继承

  上面的两种继承模式的特色为:类式继承是经过子类的原型prototype对父类实例化来实现的。构造函数式继承是经过在子类的构造函数做用环境中执行一次父类的构造函数来实现的。组合继承是组合这两种模式的优势来实现的。

   

function SuperClass(name){
    this.name = name;
    this.books = [1,2,3];
}
function SubClass(name){
    // 构造函数继承  继承父类构造函数的共有属性
    SuperClass.call(this,name)
}
// 类式继承 继承父类原型上的方法
SubClass.prototype = new SuperClass();

该模式的继承的缺点很明确即调用了两次父类构造函数。

4、洁净的继承者--原型式继承

// 原型式继承
function inheritObject(obj){
    // 声明一个过渡函数对象
    function F(){}
    // 过渡对象的原型继承父对象
    F.prototype = obj;
    // 返回过渡 对象的一个 实例,该实例的原型继承了父对象
    return new F()
}

其实原型式继承就是对类式继承的一个封装,其实其中的过渡对象就至关于类式继承的子类,只不过在原型中做为一个过渡对象出现的,目的是为了建立要返回的新的实例化对象。

由于是对类式继承的封装,因此类式继承的缺点在这里也存在,即父类对象的引用类型的属性被共用。

该方法与Object.create()相似

5、寄生式继承

//  声明基对象
var book = {
    name : "hyh",
    books:[1,2,3]
}
function createBook(obj){
    // 经过原型继承的方法建立新对象
    var o = new inheritObject(obj)  
    // 拓展新对象    
    o.getName = function(){
        return this.name
    }
    // 返回拓展后新对象
    return o
}
var newBook = createBook(book)

 该模式的继承就是对原型继承进行的二次封装,而且在封装的过程当中继承的对象进行了拓展,这样新建立的对象不单单有父类中的属性和方法并且还添加了新的属性和方法。

6、终极继承者--寄生组合式继承

  该模式是对寄生式继承(寄生式继承依托于原型继承,原型继承与类式继承相像)与构造函数继承的组合。这里的寄生式继承不是对对象的处理,而是对类的原型(实质上也是对象)。

/**
 * 终极继承者 -- 寄生组合式继承
 * SubClass  子类
 * SuperClass 父类
 */

 function inheritPrototype(SubClass, SuperClass){
    // 复制一份父类的原型副本保存在变量中
    var p = inheritObject(SuperClass.prototype);
    // 修正由于重写子类原型致使子类的 constructor 属性被修改
    p.constructor = SubClass;
    SubClass.prototype = p;
 }
// 原型式继承
function inheritObject(obj){
    // 声明一个过渡函数对象
    function F(){}
    // 过渡对象的原型继承传入的对象(即父构造函数的原型)
    F.prototype = obj;
    // 返回过渡对象的一个实例,该实例的原型继承了传入的对象
    return new F()
}

 

 function inheritPrototype(SubClass, SuperClass){
    // 复制一份父类的原型副本保存在变量中
    var p = inheritObject(SuperClass.prototype);
    // 修正由于重写子类原型致使子类的 constructor 属性被修改
    p.constructor = SubClass;
    SubClass.prototype = p;
 }
// 定义父类构造函数
 function SuperClass(name){
     this.name = name;
     this.arr = [1,2,3];
 }
//  定义父类的原型方法
 SuperClass.prototype.getName = function(){
     return this.name;
 }
//  定义子类
 function SubClass(name, age){
    //  构造函数式继承 继承父类的共有属性(构造函数内部的属性)
    SuperClass.call(this, name);
    // 子类新增的属性
    this.age = age;
 }
//  寄生式继承父类原型
 inheritPrototype(SubClass, SuperClass);
//  这里子类给原型添加方法只能经过点的语法来添加,不会会覆盖前面的原型对象
 SubClass.prototype.getTime = function(){
     return this.name
 }
//  建立两个子类实例
var i1 = new SubClass("hyh",20);
var i2 = new SubClass("qls",18);
i1.arr.push(4)
console.log(i1.arr)   // [1,2,3,4]
console.log(i2.arr)   // [1,2,3]

 

相关文章
相关标签/搜索