js中的四大继承方案

266 阅读3分钟
  • 原型继承
  • 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.自己写插件或者类库的时候