第一种:构造函数继承
核心思想:使用call()
改变子类的this
指向父类,使其子类实例拥有父类的属性和方法
代码:
function Person(name){
this.name = name
this.hello = function(){
console.log('hello')
}
}
Person.prototype.introduce = function(){
console.log('你好,我叫' + this.name)
}
function Student(name, xh){
Person.call(this, name)
this.xh = xh
}
let stu = new Student('张三', 20190345)
console.log(stu)
stu.hello()
stu.introduce() //报错
优点:
子类构造函数向父类构造函数中传递参数
可以实现多继承(call或者apply多个父类)
缺点:
方法都在构造函数中定义,无法复用
不能继承原型属性/方法,只能继承父类的实例属性和方法
第二种:原型链继承
核心思想:父类实例作为子类的原型
优点:方法复用,服用了父类原型链上的方法
缺点:创建子类实例时,不能向构造函数传参;子类实例共享了父类构造函数的引用属性;
function Parent(name){
this.name = name || '父亲'
this.arr = [1]
}
Parent.prototype.say = function(){
console.log('hello')
}
function Child(like){
this.like = like
}
Child.prototype = new Parent()
Child.prototype.constructor = Child
第三种:组合继承
代码:
function Parent(name){
this.name = name
this.arr = [1]
}
Parent.prototype.say = function(){
console.log('hello')
}
function Child(name, like){
Parent.call(this, name)
this.like = like
}
Child.prototype = new Parent()
Child.prototype.constructor = Child
优点:可以向父类构造函数传参;可以复用父类原型上的方法;不共享父类的引用属性
缺点:两次调用了父类的构造函数,会存在一份多余的父类实例对象
第四种:组合继承优化
代码:
function Parent(name){
this.name = name
this.arr = [1]
}
Parent.prototype.say = function(){
console.log('hello')
}
function Child(name, like){
Parent.call(this, name)
this.like = like
}
Child.prototype = Parent.prototype
第五种:寄生组合继承
完美
代码:
function Parent(name){
this.name = name
this.arr = [1]
}
Parent.prototype.say = function(){
console.log('hello')
}
function Child(name, like){
Parent.call(this, name)
this.like = like
}
Child.prototype = Object.create(Parent.prototype)
Child.prototype.constructor = Child