原型继承
子类的prototype指向了一个父类实例//父类 Peroson 构造函数 function Person(name,age){ this.name = name this.age = age } Person.prototype.sayHi = function(){ console.log('你好啊'); } //子类 Student 构造函数 function Student(id){ this.id = id } //改变原型链指向,实现继承 Student.prototype = new Person('小明',12) let stu1 = new Student("666") stu1.name = '李四' stu1.age = 12 let stu2 = new Student("888")
优缺点
优点:
- 简单易于实现,父类的新增的实例与属性子类都能访问 缺点:
- 无法实现多继承
- 创建子类实例时,
不能向父类构造函数中传参数 原型属性上的引用类型值会被所有实例共享
借用构造函数继承
-
只能继承属性,继承不了方法//父类 Peroson 构造函数 function Person(name,age){ this.name = name this.age = age } Person.prototype.sayHi = function(){ console.log('你好啊'); } //子类 Student 构造函数 function Student(name,age,id){ //借用构造函数继承 Person.call(this,name,age) this.id = id } //初始化学生实例 let stu1 = new Student('lisi',19,'20210729') stu1.sayHi() #报错stu1.sayHi is not a function
组合式继承(伪经典继承)
原型继承 + 原型继承
调用了两次父类构造函数,生成了两份实例
//父类 Peroson 构造函数
function Person(name,age){
this.name = name
this.age = age
}
Person.prototype.sayHi = function(){
console.log('你好啊');
}
//子类 Student 构造函数
function Student(name,age,id){
Person.call(this,name,age)
this.id = id
}
//改变原型链指向
Student.prototype = new Person('小明',12)
let stu1 = new Student('张三',26,"666")
console.log(stu1);
寄生组合继承(经典继承)
-
解决组合式继承,
父类构造函数调用两次的缺点 -
依然有问题:改变了Student原型的指向,如果原先Student的原型上有方法,继承后是拿不到的,需要在改变指向后,再在原型上添加方法
Student.prototype = Object.create(Person.prototype) # 返回一个对象,指定返回对象的原型使指定参数的原型//父类 Peroson function Person(name,age){ this.name = name this.age = age } Person.prototype.sayHi = function(){ console.log('你好啊'); } //子类 Student 通过构造函数继承 function Student(name,age,id){ Person.call(this,name,age) this.id = id } //改变原型链指向 //希望直接拿到Person的原型对象 //Student.prototype = new Person('小明',12) //Object.create是ES5的语法,存在兼容性问题 # 兼容性写法 if(!Object.create){ Object.create = function(proto){ function F(){} F.prototype = proto return new F() } } Student.prototype = Object.create(Person.prototype) let stu1 = new Student('张三',26,"666") console.log(stu1);
圣杯模式继承
- 解决寄生组合继承的缺点
ES6 extends 继承
class Person{
constructor(name,age){
this.name = name
this.age = age
}
sayHi(){
console.log('Hello,world');
}
}
class Student extends Person{
constructor(name,age,id){
super(name,age)
this.id = id
}
}
let stu1 = new Student('李四',18,'123')
console.log(stu1);