当前位置: 移动技术网 > IT编程>开发语言>JavaScript > JavaScript实现继承的六种方式实例讲解

JavaScript实现继承的六种方式实例讲解

2018年02月08日  | 移动技术网IT编程  | 我要评论

JavaScript实现继承的六种方式实例讲解

1.借用构造函数

借用构造函数实现继承,就是在子类型构造函数内部调用父类型构造函数,使用apply()和call()方法将父类型的构造函数绑定在子类型上。

function SuperType(){ 
    this.colors = ["red", "blue", "green"]; 
} 
function SubType(){   
    SuperType.call(this);       //继承了 SuperType
} 
var instance1 = new SubType(); 
instance1.colors.push("black"); 
 //instance1实例得到了一个color属性的副本,改变的是instance1这个实例的color属性,而不是其原型对象中的color属性。
alert(instance1.colors);    //"red,blue,green,black" 
var instance2 = new SubType(); 
alert(instance2.colors);    //"red,blue,green"

通过使用apply()或call()方法,实际上是在新创建的SubType实例的环境下调用SuperType构造函数。SubType的每个实例都会具有自己的color属性的副本。

2.原型链继承

依靠原型链来实现继承,就是利用原型让一个引用类型继承另一个引用类型的属性和方法。

function SuperType(){
    this.property = true;
}
SuperType.prototype.getSuperValue = function(){
    return this.property;
}

function SubType(){
    this.subproperty = false;
}

SubType.prototype = new SuperType();
//创建 SuperType 的实例,并将该实例赋给SubType.prototype,这样SubType就继承了SuperType。
SubType.prototype.getSubValue = function(){
    return this.subproperty;
}

var instance = new SubType();
//存在于SuperType 的实例中的所有属性和方法,也存在于 SubType.prototype 中了。
alert(instance.getSuperValue());       //true

3.组合继承

组合继承就是将原型链和借用构造函数的技术组合到一起。

使用原型链实现对原型属性和方法的继承;通过借用构造函数来实现对实例属性的继承。这样在原型上定义的方法实现了函数的复用,又能保证每个实例都有自己的属性。

function SuperType(name){ 
    this.name = name; 
    this.colors = ["red", "blue", "green"]; 
} 
SuperType.prototype.sayName = function(){ 
    alert(this.name); 
}; 

function SubType(name, age){   
    SuperType.call(this, name);       //继承属性     
    this.age = age; 
} 

SubType.prototype = new SuperType(); 
SubType.prototype.constructor = SubType; 
//添加constructor属性是为了弥补重写原型而失去的默认constructor属性。
SubType.prototype.sayAge = function(){ 
    alert(this.age); 
}; 

var instance1 = new SubType("Nicholas", 29); 
instance1.colors.push("black"); 
alert(instance1.colors);      //"red,blue,green,black" 
instance1.sayName();          //"Nicholas"; 
instance1.sayAge();           //29 

var instance2 = new SubType("Greg", 27); 
alert(instance2.colors);      //"red,blue,green" 
instance2.sayName();          //"Greg"; 
instance2.sayAge();           //27
//instance1和instance2这两个实例分别拥有自己的属性,又拥有相同的方法。

4.原型式继承

借助原型可以基于已有的对象创建新对象,而不必因此创建自定义的类型。

function object(o){ 
    function F(){} ;
    F.prototype = o; 
    return new F(); 
}
//在 object()函数内部,先创建了一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回了这个临时类型的一个新实例。

var person = { 
    name: "Nicholas", 
    friends: ["Shelby", "Court", "Van"] 
};                  
//person对象作为后续对象的继承,后续的对象在person的基础上根据具体的需求进行修改。

var anotherPerson = object(person); 
//创建的新对象将person作为原型。原型中包含一个基本类型值的属性和一个引用类型值的属性,那么这个引用类型值的属性friends,将会共享给新创建的对象。
anotherPerson.name = "Greg"; 
anotherPerson.friends.push("Rob"); 

var yetAnotherPerson = object(person); 
yetAnotherPerson.name = "Linda"; 
yetAnotherPerson.friends.push("Barbie"); 

alert(person.friends);   //"Shelby,Court,Van,Rob,Barbie"

ES5提供了Object.create()方法来实现原型式继承

两个参数:用作新对象原型的对象、为新对象定义其他属性的对象(可选)。

只传入一个参数时,Object.create()方法和object()方法行为相同:

var person = { 
    name: "Nicholas", 
    friends: ["Shelby", "Court", "Van"] 
}; 
var anotherPerson = Object.create(person); 
anotherPerson.name = "Greg"; 
anotherPerson.friends.push("Rob");
console.log(person);

  Object.create()方法的第二个参数与Object.defineProperties()方法的第二个参数格式相同:每个属性都通过自己的描述符定义。重新定义的属性会覆盖原型对象上的同名属性。

var anotherPerson = Object.create(person, { 
    name: { 
        value: "Greg" 
    } 
});   
alert(anotherPerson.name); //"Greg"

5.寄生式继承

寄生式继承的思路与寄生构造函数和工厂模式类似,即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后再像真地是它做了所有工作一样返回对象。

function createAnother(original){ //参数original是作为新对象基础的对象
    var clone = object(original);  //通过调用函数创建一个新对象 
    clone.sayHi = function(){      //以某种方式来增强这个对象 
        alert("hi"); 
    }; 
    return clone;                  //返回这个对象 
} 

var person = { 
    name: "Nicholas", 
    friends: ["Shelby", "Court", "Van"] 
}; 
var anotherPerson = createAnother(person); 
anotherPerson.sayHi(); //"hi"
//基于person返回了一个新对象。新对象不仅拥有person的所有属性和方法,同时也拥有自己的sayHi()方法。

6.寄生组合式继承

寄生组合式继承:通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。本质上就是使用寄生式继承来继承超类型的原型,再将结果指定给子类型的原型。

function inheritPrototype(subType, superType){ 
    var prototype = Object(superType.prototype);     //创建对象 
    prototype.constructor = subType;                //增强对象 
    subType.prototype = prototype;                  //指定对象 
} 

函数接受两个参数:子类型和超类型。

第一步:创建超类型原型的一个副本。

第二步:为创建的副本添加属性,这里添加的constructor 属性是为了弥补因重写原型而失去的默认的 constructor 属性。

第三步:将新创建的对象赋值给子类型的原型。

function SuperType(name){ 
    this.name = name; 
    this.colors = ["red", "blue", "green"]; 
} 
SuperType.prototype.sayName = function(){ 
    alert(this.name); 
}; 

function SubType(name, age){   
    SuperType.call(this, name); 
    this.age = age; 
} 

inheritPrototype(SubType, SuperType); 

SubType.prototype.sayAge = function(){ 
    alert(this.age); 
}; 

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网