ES5的继承
原型链继承
//父类
function Father() {
this.name = 'abc'
this.age = 10
this.hobby =['篮球','足球','乒乓球']
}
//子类
function Son() {
}
Son.prototype = new Father()
var obj = new Son()
var obj1 = new Son()
obj1.name = 'cba'
obj1.hobby.push('网球')
console.log(obj.name)
console.log(obj.age)
console.log(obj.hobby)
console.log(obj1.name)
console.log(obj1.age)
console.log(obj1.hobby)
原理:将需要继承的父类充当子类的原型对象来进行调用
优点:简单方便,操作简单
缺点:1.不能传递父类的参数
2.子类的原型对象(所继承的父类)中的引用属性(引用数据类型)是共享的。在上述代码中,在父类的hobby为一个数组对象,可以看见我们创建出obj,obj1两个对象,只修改obj1中的hobby,obj也会随之改变.
构造函数继承
// 父类
function Father(name,age) {
this.name = name
this.age = age
this.hobby =['篮球','足球','乒乓球']
}
//子类
function Son(name,age) {
Father.call(this,name,age)
}
var obj =new Son('abc',10)
var obj1 =new Son('cba',20)
console.log(obj.name)
console.log(obj.age)
console.log(obj1.name)
console.log(obj1.age)
console.log(obj1.hobby === obj.hobby)
原理:借用父类的构造函数来增强子类实例,等于是把父类的实例属性复制一份给子类实例装上
优点:1.可以传递父类的参数
2可以实现多个父类的继承
缺点:1.不能继承父类上的原型方法
2.每个创建的子类都是一个新的函数,内存消耗极大
组合继承
// 父类
function Father(name,age) {
this.name = name
this.age = age
this.hobby =['篮球','足球','乒乓球']
Father.prototype.sex = function () {
console.log('男')
}
}
//子类
function Son(name,age) {
Father.call(this,name,age)
}
Son.prototype = new Father()
Son.prototype.constructor = Son
var obj =new Son('abc',10)
obj.sex()
.
原理:将原型链继承和构造函数继承相结合
优点:比较完美
缺点:1.操作复杂
2.调用了2次父类
ES6继承
extends关键字继承
class Father{
constructor(name,age) {
this.name =name
this.age = age
}
sex(){
console.log('男')
}
}
class Son extends Father{
constructor(name,age) {
super(name,age);
}
}
obj =new Son('abc',30)
console.log(obj.name)
console.log(obj.age)
obj.sex()
原理通过extends关键字来继承父类,子类可以继承父类的属性和方法,子类必须在constructor方法中调用super()方法来实现,因为新建的子类是没有自己的this对象,而是继承了父类的this对象
ES5继承与ES6继承的区别
es5的继承实质是先创建子类的实质对象this,然后再把父类的方法添加到子类的this上
es6的继承是先把父类实例对象的属性和方法添加到this上,然后再用子类的构造函数去修改this