zoukankan      html  css  js  c++  java
  • js中ES5的继承

    js中ES5的继承

    js的前期是没有类的这种说法,更不用说是继承了,于是创建出了很多继承的方式,经历很多个版本,实现了类似继承的方法。

    3种有问题的继承方式

    1.原型式继承

    function Box(v){        //父类Box的创建
        this.v=v;
        console.log(v);
    }
    Box.prototype.run=function(){   //Box原型方法的创建
    
    }
    Box.prototype.a=10;
    
    function Ball(v){   //子类的创建
       
    }
    Ball.prototype=new Box();  //原型式继承 就是父类的实例化赋值到子类的原型上
    Object.defineProperty(Ball.prototype,"constructor",{   //没有constructor,只能自己创建
        value:Ball
    })
    var c=new Ball(3);   //但是constructor还是不能像ES6一样
    console.log(c);
    

    2.组合继承(原型继承和冒充继承)

    function Box(v){        
        this.v=v;
        console.log(v);
    }
    Box.prototype.run=function(){  
    
    }
    Box.prototype.a=10;
    
    function Ball(v){   
    //这是冒充继承(改变父类this指向)
       Box.call(this,v);  //为了解决constructor不能正常工作    把Box的this指向改为Ball(子类)的,但是new  Ball的时候,Box的constructor可以正常工作,new Box还是不能解决
    }
    Ball.prototype=new Box();  
    Object.defineProperty(Ball.prototype,"constructor",{   
        value:Ball
    })
    var c=new Ball(3);  
    console.log(c);
    

    完全实现继承的方式

    • 寄生式继承(原型继承,冒充继承,中间函数)
    function Box(v){
        this.v=v;
        console.log(v);
    }
    Box.prototype.run=function(){
    
    }
    Box.prototype.a=10;
    
    
    function F(){   //中间类(函数)
    
    }
    F.prototype=Box.prototype;  (父类的原型赋值给中间函数的原型上)
    
    
    function Ball(v){
        Box.call(this,v);
    }
    Ball.prototype=new F();   //中间函数的实例赋值给子类原型
    Object.defineProperty(Ball.prototype,"constructor",{
        value:Ball
    })
    
    var c=new Ball(3);
    console.log(c) 
    

    寄生式继承的封装

    
    Function.prototype.extend = function (superClass) {   //参数是父类
        function F() { }  //中间函数
        F.prototype = superClass.prototype;
        var proto = this.prototype;  //子类的原型  原因:后面的new  F会覆盖原来的属性,所以提前拿出来
        this.prototype = new F();   //中间类的实例赋值给子类原型
        var names = Object.getOwnPropertyNames(proto);  //获取子类原型上的所有方法和属性名
        for (var i = 0; i < names.length; i++) {      //遍历原来的属性名,new F()后,重新弄上去
            var desc = Object.getOwnPropertyDescriptor(proto, names[i]);
            Object.defineProperty(this.prototype, names[i], desc);
        }
        Object.defineProperty(this.prototype, "constructor", {
            value: this,
        });
        this.prototype.superClass = superClass;
        if (superClass.prototype.constructor !== superClass) {
            Object.defineProperty(superClass.prototype, "constructor", {
                value: superClass,
            });
        }
    };
    
    //继承组件的使用
    function Box(v) {
        this.v = v;
        console.log(v);
      }
      Box.prototype.run = function () {
          console.log("a");
      };
      Box.prototype.a = 10;
    
      function Ball(v) {   constructor中的super
         this.superClass.apply(this,arguments);
      }
      Ball.prototype.play=function(){
    
      }
      Ball.extend(Box);
      Ball.prototype.run=function(){    子类方法中继承父类的这个方法   相当于ES6中的super.run();
         this.superClass.prototype.run.apply(this,arguments);
         console.log("b");
      }
    
      var c=new Ball(5);
    console.log(c);
    c.run();
    
  • 相关阅读:
    zabbix学习笔记----概念----2019.03.25
    用深信服AC控制方位话机注册链路的开、关
    方位话机冗余线路注册问题测试过程
    执行python文件报错SyntaxError: Non-ASCII character 'xe8' in file, but no encoding declared
    centos 7.4安装python3.7.4
    zabbix基础使用--添加ping监控
    snmp监控f5
    FortiGate 服务License注册步骤
    centos 7.4安装zabbix 3
    安装centos 6.7&7.4
  • 原文地址:https://www.cnblogs.com/94-Lucky/p/13509460.html
Copyright © 2011-2022 走看看