ES5中基于原型链实现继承

94 阅读2分钟

在ES5中并没有class这个概念,如果要实现继承关系,需要通过修改原型链来实现,事实上在ES6中,即使已经有了class这个概念,继承的底层实现依然是原型链。

我们先来看一段代码:

class Person{
    constructor(name,age) {
        this.name=name;
        this.age=age;
    }
    run(){
        console.log("running")
    }
    show(p){
        console.log(`我叫${this.name},我今年${this.age}岁`)
    }
}
class Student extends Person{
    constructor(name,age) {
        super(name,age);
    }
    show(c){
        console.log('彦祖');
    }
}
class Teacher extends Person{}
let student=new Student("吴彦祖",19);
console.log(student);
let teacher=new Teacher("国服第一百里守约",20);
student.show();
teacher.show();

输出结果如下:

image.png

根据上述原理,我们在ES5中通过ES6继承原理来实现继承如下:

//定义Person构造函数
function Person(name,age){
    this.name=name;
    this.age=age;
}
Person.prototype.showName=function(){
    console.log(this.name);
}
//子类原型指向父类的实例对象
//子类实例会将父类实例中的属性继承下来
//父类实例中会拥有子类原型中的方法
//定义Student构造函数
function Student(name,age,no){
    let person=new Person(name,age);//创建一个父类实例对象
    this.no=no;
    //将父类实例中的属性继承到子类实例中
    for(property in person){//遍历person对象中所有的属性
        if(person.hasOwnProperty(property)){//判断person对象中是否拥有该属性(不判断原型链)
            this[property]=person[property];
            delete person[property];
        }
    }
    //将子类原型中的函数放到父类实例中去
    for(fun in Student.prototype){
        if(Student.prototype.hasOwnProperty(fun)){//判断person对象中是否拥有该属性(不判断原型链)
            person[fun]=Student.prototype[fun];
        }
    }
    //子类原型指向父类实例
    Student.prototype=person;
    this.__proto__=person;
}
Student.prototype.showNo=function(){
    console.log(this.no);
}

let student= new Student("张三",19,9527);
console.log(student);
let student1=new Student("李四",18,9527);
console.log(student1);

通过这种原型链的方式实现继承,完全满足了继承的要求。

  1. 子类可以使用父类的属性
  2. 子类可以调用父类的函数
  3. 子类存在和父类中相同的函数,优先调用子类自己的函数

无论你在学习上有任何问题,重庆蜗牛学院欢迎你前来咨询,联系QQ:296799112