JS学习记录(2) 常用的三种继承(2021-10-16)

一、对象继承
//2.12.7 对象继承

//  2.12.7.1 原型链继承:【核心思想:子类型的原型为父类型的一个实例对象】

//1、定义父类型构造函数
function SupperType(){
    
    
    this.supProp = "Supper property";
}

//2、给父类型的原型添加方法
SupperType.prototype.showSupperProp = function(){
    
    
    console.log(this.supProp);
};

//3、定义子类型的构造函数
function SubType(){
    
    
    this.subProp = "Sub property";
}

//4、创建父类型的对象赋值给子类型的原型
SubType.prototype = new SupperType();

//5、将子类型原型的构造属性设置为子类型
SubType.prototype.constructor = SubType ;

//6、给子类型原型添加方法
SubType.prototype.showSubProp = function(){
    
    
    console.log(this.subProp);
} ;

//7、创建子类型的对象,可以调用父类型的方法
var SubType = new SubType();
SubType.showSupperProp();
SubType.showSubProp();

/*结果:
Supper property
Sub property
缺点:
1、原型链继承多个实例的引用类型属性指向相同,一个实例修改了原型属性,
另一个实例的原型属性也会被修改
2、不能传递参数
3、继承单一
*/
二、借用构造函数继承
```javascript


//  2.12.7.2 借用构造函数继承
/*      【核心思想: 使用.call()和.apply()将父类构造函数引入子类函数,
     使用父类的构造函数来增强子类实例,等同于复制父类的实例给子类】

        借用构造函数继承的重点就在于SuperType**.call(this, name)**,
    调用了SuperType构造函数,这样,SubType的每个实例
    都会将SuperType中的属性复制一份。
*/

// 1、定义父类型的构造函数
function  SuperType(name){
    
    
    this.name = name ;
    this.showSupperName = function(){
    
    
        console.log(this.name);
    };
}

// 2、定义子类型的构造函数
function SubType_1(name,age){
    
    
    // 在子类型中调用call方法继承自SuperType
    SuperType.call(this,name);
    this.age = age;
}


// 3、给子类型的原型添加方法s
SubType_1.prototype.showSubName = function(){
    
    
    console.log(this.name);
};

// 4、创建子类型的对象然后调用
var subType = new SubType_1("构造函数继承",20);
subType.showSupperName();
subType.showSubName();
console.log(subType.name);
console.log(subType.age);

/*结果:
P111
P111
P111
20

缺点:
1、只能继承父类的实例属性和方法,不能继承原型属性和方法
2、无法实现构造函数的复用,每个子类都有父类实例函数的副本,影响性能,代码会臃肿
*/
三、混合继承
//  2.12.7.3 组合继承【核心思想: 原型链+借用构造函数的组合继承】

// 利用原型链实现对父类型对象的方法继承
// 利用super()借用父类型构建函数初始化相同属性
// JS中最常用的继承模式
function Person(name,age){
    
    
    this.name = name;
    this.age = age;
}

Person.prototype.setName = function(name){
    
    
    this.name = name;
};

function Student(name,age,price){
    
    
    Person.call(this,name,age);//为了得到父类型的实例属性和方法
    this.price = price;//添加子类型私有的属性
}

Student.prototype = new Person();
Student.prototype.constructor = Student;
Student.prototype.setPrice = function(price){
    
    
    this.price = price;
};

var s = new Student("组合继承",24,15000);
console.log(s.name,s.age,s.price);
s.setName("组合继承2");
s.setPrice(16000);
console.log(s.name,s.age,s.price);
/*结果:
组合继承 24 15000
组合继承2 24 16000

缺点:
父类中的实例属性和方法既存在于子类的实例中,又存在于子类的原型中,
不过仅是内存占用,因此,在使用子类创建实例对象时,
其原型中会存在两份相同的属性和方法。
*/

猜你喜欢

转载自blog.csdn.net/ariarko/article/details/120805909
今日推荐