前言
JS本身是基于面向对象开发的编程语言
**类:**封装、继承、多态
**封装:**类也是一个函数,把实现一个功能的代码进行封装,以此实现“低耦合,高内聚”
**多态:**重载、重写
**重写:**子类重写父类上的方法(伴随着继承运行的)
**重载:**相同的方法,由于参数或者返回值不同,具备了不同的功能(JS中不具备严格意义上的重载)
**JS中的重载:**同一个方法内,根据传参的不同实现不同的功能
JS中的继承
在JS语言中,它的继承和其他编程语言还是不太一样
**继承的目的:**让子类的实例同时也具备父类中的私有属性和公共方法
原型继承
**JS中的第一种继承方法:**原型继承,让子类的原型等于父类的实例即可
Child.prototype = new Parent;//=>原型继承
//后面还可以给原型里面手动添加公共方法
//这样Child的实例既可以用自己私有的属性和方法,也可以通过原型链找到Parent里面的私有的和公共的属性和方法,都可以调用了
特点:
1)父类中私有和公有的属性和方法最后都变为子类实例公有的
2)和其他的语言不同的是,原型继承并不会把父类的属性和方法“拷贝”给子类,而是让子类实例基于____proto____ 原型链找到自己定义的属性和方法“指向/查找”方式的
3)通过原型链修改子类原型(原有父类的一个实例)中的内容,内容被修改后,对子类的其它实例有影响,但是对父类的实例不会有影响
4)如果通过原型链直接修改的是父类的原型,这样不仅会影响其它父类的实例,也影响其它子类的实例
注: IE低版本浏览器中禁止使用____proto____ 这个属性,防止原型被修改
**注意:**这种继承方式抛弃了类原有的原型,原有的原型上的公共方法就没了;另外,只能改变自己自定义的类的原型,内置的类的原型是无法重定向的。
call继承
**JS中第二种继承方式:**call继承
new Child 构造函数执行的时候,
在Child函数类里面加一个Parent.call(this),用call改变父类执行的this,把this变为了Child的一个实例,这样就相当于让子类的实例继承了父类的私有属性,并且也变为了子类私有的属性,“拷贝式”
特点: 只能继承父类中私有的属性和方法,不能继承父类中公共的属性和方法(父类原型上的继承不了)
寄生组合式继承
**JS中第三种继承方式:**寄生组合式继承继承(call继承+另类原型继承)
我们的目的是让父类的私有属性和方法也变成子类的私有属性和方法,让父类的原型的公共方法也是子类的公共方法。而原型继承是把父类的私有和公有都变成了子类的公有,这样不太完美。所以寄生组合式继承是比较完美的继承。需要手动加constructor。其实运用的就是原型重定向,再在重定向之后,手动添加一些属性和方法。
Child.prototype.__proto__ = Parent.prototype
let obj={xxx:xxx};
Object.create(obj)
Object上有create方法,创建一个空对象,并且让它的原型链指向obj
Child.protorype = Object.create(Parent.prototype)
这样子类的实例就指向了这个空对象,通过原型链再找到父类的原型
ES6中的继承
继承:extends Parent(类似于继承组合式继承)
注意:继承以后一定要在constructor的第一行加上super()
class Child extends Parent{
constructor(num1){
super(num2);
this.x = 100;
}
getX(){
}
}
如果继承了,super就必须要写,并且要在constructor的首行写。有了class B extends A,constructor里面就必须有super(),super传参是多少,constructor里面传参就是多少,B执行,然后super执行,则A构造函数也执行了。
相当于 extends 是继承公有属性,super继承私有属性
super() 类似于之前的call继承,super(100,200)相当于把Parent中的constructor执行,传递了100和200