- 原型继承
- call继承
- 寄生组合继承
- class实现继承
在学习继承之前,先了解下面向对象的几个特征:封装、继承、多态
封装:把要实现的代码放在一个函数里面,能实现它的复用性,这就是封装。
多态:重载和重写
在Java中重载:函数名相同、但是传参类型、数量不同或者返回值不一样,这相当于把一个函数重载了(js中没有类似于后台语言中的重载机制:js中的重载指的是同一方法,根据传参不同,实现不同的业务逻辑)
// java的重载
public String fn(int n,int m){
}
public String fn(int n){
}
public String fn(int n,double m){
}
fn(10,20)
fn(10)
fn(10,20.86)
<script>
// js的重载
function fn(n,m){
if(!m){
//....
}
}
fn(10,20)
fn(10)
</script>
重写:子类重写父类上的方法
继承:子类继承父类中的属性和方法(js中继承机制和其他后台语言是不一样的,有自己独特处理方式)
一、js中继承方式一:原型继承
原型继承:让子类的原型指向父类的实列
几大特征:
- 1.并不会把父类中的方法克隆一份给子类,而是建立了子类和父类之间的原型链的查找机制
- 2.重定向子类的原型后,默认丢失了原本的constructor(或者原本在原型上设置的属性和方法)
- 3.子类或者子类的实列,可以基于原型链
"肆意"修改父类上属性方法,对父类造成一些"不必要的破坏" - 4.会把父类中私有的属性方法做为子类公有属性方法继承过来(父类中不管是公有还是私有,最后都变成子类公有的)
<script>
// 假如B是子类 A是父类 让B继承父类中的属性和方法
function A(){
this.x=100;
}
A.prototype.getX=function getX(){
console.log(this.x);
}
function B(){
this.y=200;
}
B.prototype.sum=function(){}
B.prototype=new A;
B.prototype.getY=function getY(){
console.log(this.y);
};
let b=new B;
</script>
二、js中继承方式二:call
call继承:把父类当做普通函数执行,让其执行的时候方法中this变为子类的实列即可
特征:
- 1.只能继承父类中的私有属性(继承的私有属性赋值给子类实例的私有属性)而且是类似拷贝过来一份,而不是链式查找
- 2.因为只是把父类当做普通的方法执行,所以父类原型上的共有属性方法无法继承过来
<script>
// 把A函数当做普通函数执行 让函数里的this变成函数的实列
function A(){
this.x=100;
}
A.prototype.getX=function getX(){
console.log(this.x);
}
function B(){
// call继承
A.call(this); //=>this.x=100; 相当于b.x=100
this.y=200;
}
B.prototype.getY=function getY(){ console.log(this.y);
};
let b=new B;
console.log(b); //B{x:100 y:200}
</script>
三、js中继承方式三:寄生组合继承
寄生组合继承:call继承+变异版的原型继承公共完成的
call继承实现:私有到私有
原型继承实现:公有到公有
function A(){
this.x=100;
}
A.prototype.getX=function getX(){
console.log(this.x);
}
function B(){
A.call(this);
this.y=200;
}
//=>object.create(OBJ)创建一个空对象,让其__proto__指向OBJ(把OBJ作为空对象的原型)
B.prototype=Object.create(A.prototype);
B.prototype=constructor=B;
B.prototype.getY=function getY(){
console.log(this.y
);
};
let b=new B;
console.log(b);
四、js中继承方式四:class实现继承
<script>
class A{
constructor(){
this.x=100;
}
getX(){
console.log(this.x);
}
}
// extends继承和寄生组合继承基本类似
class B extends A{
constructor(){
super();//=>一旦使用extends实现继承,只要自己写了constructor就必须写super =>A.call(this)
this.x=200;
}
getY(){
console.log(this.y);
}
}
let b=new B;
</script>
真实项目使用继承的地方
1.react创建类组件
2.自己写插件或者类库的时候