-
构造函数继承(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)方法都在构造函数中定义,每次创建实例都会创建一遍方法。
-
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
-
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();//我的专业是前端开发
继承是可以延续的