《JS的继承》

81 阅读2分钟
  1. 构造函数继承(call和apply的区别在于,传入参数的形式不同)

function person(name){
  this.name = name;
  this.speak = ()=>{
    console.log(this.name);
  }
}
function student(name){
  person.call(this,name);
}
const peng = new student('我是一名学生,我叫peng');
peng.speak();  //   "我是一名学生,我叫peng"
  • 优点

(1)避免引用类型数据共享
(2)创建子类的时候可以向父类传参

  •  缺点

(1)方法都在构造函数中定义,每次创建实例都会创建一遍方法。

  1. prototype模式

  • 子类原型 = 父类实例
//原型链继承之子类原型 = 父类实例
function person(name){
  this.name = name;
     this.speak = function(){
        console.log(this.name)
    }
}
person.prototype.say =function(){
    console.log("我是中国人")
}
function student(name){
  this.name = name;
}
student.prototype = new person();
student.prototype.constructor = student;
const peng = new student('我是一名学生,我叫peng');
peng.speak();  //"我是一名学生,我叫peng"
peng.say();  //"我是中国人"

student.prototype = new person();

相当于完全删除了prototype 对象原先的值,然后赋予一个新值
加了这一行以后,student.prototype.constructor指向person。

alert(cat1.constructor == Animal); // true

显然会导致继承链的紊乱(peng明明是用构造函数student生成的),因此我们必须手动纠正,将student.prototype对象的constructor值改为student

代码如下

student.prototype.constructor = student;
  • 子类原型 = 父类原型
//原型链继承之子类原型 = 父类原型
function person(name){}
person.prototype.say =function(){
    console.log("我是中国人")
}
function student(name){}
student.prototype = person.prototype;
student.prototype.constructor = student;
const peng = new student("我是一名学生,我叫peng");
console.log(person.prototype.constructor==student)
peng.say(); //"我是中国人"

student.prototype = person.prototype;

第一种:可以继承父类构造函数的各个属性和方法,但要new一个子类实例

第二种: 优点:是效率比较高(不用执行和建立person的实例了),比较省内存 将student的prototype对象,然后指向person的prototype对象,这样就完成了继承。

缺点:是 student.prototype和person.prototype现在指向了同一个对象,那么任何对Cat.prototype的修改,都会反映到Animal.prototype

  1. class类的继承

当有很多的class并且这些class中有很多公共属性的时候我们就可以使用继承。

比如一个公司里面有学生,老师,保安。。。等,它们都有共同属性都是人,都会说话等等。
这些公共的属性就可以作为一个基础的类供学生,老师,保安继承。

实现公共类

//公共类
class person{
  constructor(name,job){
    this.name= name;
    this.job = job;
    this.school = "饥人谷";
  }
  say(){
    console.log(`我是${this.school}的一名${this.job},我的名字是${this.name}`)
  }
}

实现学生类

//学生类
class student extends person{
  constructor(name,job,number){
    super(name,job)
    this.number = number;
    }
    sayName(){
      console.log(`我是${this.name},我的学号是${this.number}`);
  }  
}
const peng = new student("peng","学生",026);
peng.say(); //我是饥人谷的一名学生,我的名字是peng
peng.sayName();//我是peng,我的学号是22

实现学生类扩展专业

class grade extends student{
  constructor(name,job,number,grade){
    super(name,job,number);
    this.grade  = grade;
    }
  sayGrade(){
    console.log(`我的专业是${this.grade}`);
  }
}
const frank = new grade("frank","学生",026,"前端开发");
frank.say();//我是饥人谷的一名学生,我的名字是frank
frank.sayName();/我是frank,我的学号是22
frank.sayGrade();//我的专业是前端开发

继承是可以延续的