Js的继承

js的继承

@(js)[继承, js, 前端]

组合继承是原性链继承和构造函数继承的合体,它汲取了二者各自的有点,同时又互相补充了各自的弱点,是一种应用十分广泛的JavaScript继承模式。下面分别从原性链继承、构造函数继承分别开始介绍,最后介绍二者的结合——组合继承。

一、原型链

利用原型让一个引用类型继承另一个引用类型的属性和方法
每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。

实现原性链的基本模式:

function SuperType(){  //定义了一个父函数
    this.property =true;  
}  
SuperType.prototype.getSuperValue = function(){    //给父函数的原型链上添加一个getSuperValue的函数
    returnthis.property;  
}  

function Subtype(){    //定义一个子函数
    this.subproperty =false;  
}  
SubType.prototype = new SuperType();  //SubType实现了继承SuperType  
SubType.prototype.getSubValue = function(){    //给子函数添加方法
    return this.subproperty;  
}  
var instance = new SubType();  // 实例instance继承子函数
alert(instance.getSuperValue());  

最后的结果:intance指向SubType的原型,而SubType的原型又指向SuperType的原型,SuperType继承了Object,所有函数的默认原型都是Object的实例

问题:会产生引用类型值的问题
比如,创建了一个子类的实例,如果对子类实例的属性进行了修改,那么创建其他子类的时候都会收到影响,代码如下:

function SuperType(){  
    this.colors =[“red”, “blue”, “green”];  
}  
function SubType(){  
}  
SubType.prototype = new SuperType();  
var instance1 = new SubType();  
instance1.colors.push(“black”);  
alert(instance1.colors);  //red, blue, green, black  
var instance2 = new SubType();  
alert(instance2.colors);   //red, blue, green, black    

以上结果说明会影响其他实例的属性值

二、借用构造函数

在子类型构造函数的内部调用超类型构造函数

function SuperType(){    // 定义一个父函数
    this.colors =[“red”, “blue”, “green”];  
}  
function SubType{}(   // 定义一个子函数
   SuperType.call(this);     // 继承了父函数
}  
var instance1 = new SubType();    // 实例instance1继承子函数
instance1.colors.push(“black”);  
alert(intance1.colors);     //red,blue,green,black  

var instance2 = new SubType();  // 实例instance2继承子函数
alert(instance2.colors);   //red,blue,green  

使用该方法可以在子类构造函数中向超类型构造函数传递参数,如下:

function SuperType(name){    // 定义父函数
    this.name = name;  
}  
function SubType(){    // 定义子函数
SuperType.call(this,“Nicholas”);        //传入参数,利用这个参数初始化父类构造函数中的name  
this.age = 29;  
}  

var instance = new SubType();  // 实例instance继承子函数
alert(instance.name);   //Nicholas  
alert(instance.age);   //29  

问题:不方便复用

三、组合式继承
使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承
示例代码:

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);    //继承SuperType的一部分,this指SubType,  
this.age = age;    //自己新定义的属性age也可以进行赋值  
}  
SubType.prototype = new SuperType();     //利用原型继承,可以使用父类的方法
  
SubType.prototype.sayAge = function(){   //定义SubType特有的新方法  
    alert(this.age);  
}  
var instance1 = new SubType(“Martin”, 10);  
instance1.colors.push(“black”);  
alert(instance1.colors);  //red,blue,green,black  
instance1.sayName();   //Martin  
instance1.sayAge();  //10  

var instance2 = new SubType(“Greg”, 27);  
alert(instance2.colors);   //red,blue,green  
instance2.sayName();  //Greg  
instance2.sayAge();  //27 

综合例子:

function Person(name, age) {
    this.name = name;
    this.age = age;
}

Person.prototype.hi = function() {
    console.log('Hi, my name is' + this.name) + ",I'm" + this.age + 'years old now.';
};

Person.prototype.LEGS_NUM = 2;
Person.prototype.ARMS_NUM = 2;
Person.prototype.walk = function() {
    console.log(this.name + "is walking...");
}

function Student(name, age, className) {
    Person.call(this, name, age);
    this.className = className;
}

Student.prototype = Objectcreate(Person.prototype);
Student.prototype.constructor = Student;

Student.prototype.hi = function() {
    console.log('Hi, my name is' + this.name + ", I'm" + this.age + "years old now, and from" + this.className + ".");
}

Student.prototype.learn = function(subject) {
    console.log(this.name + 'is learing' + subject + 'at' + this.className + '.');
}

// test
var bosn = new Student('Bosn', 27, 'Class 3,Grade 2');
bosn.hi();  // Hi, my name is Bosn, I'm 27 years old now and from Class3,Grage 2
bosn.LEGS_NUM; // 2
bosn.walk();  // Bosn is walking
bosn.learn('math');  // Bosn is learning math t Class3, Grade 2.

你可能感兴趣的:(Js的继承)