美文网首页程序员让前端飞
JavaScript中的继承及实现代码

JavaScript中的继承及实现代码

作者: 88b61f4ab233 | 来源:发表于2018-12-14 19:35 被阅读12次

    JS虽然不像是JAVA那种强类型的语言,但也有着与JAVA类型的继承属性,那么JS中的继承是如何实现的呢?

    一、构造函数继承

    在构造函数中,同样属于两个新创建的函数,也是不相等的
     function Fn(name){
      this.name = name;
      this.show = function(){
       alert(this.name);
      }
     }
     var obj1 = new Fn("AAA");
     var obj2 = new Fn("BBB");
     console.log(obj1.show==obj2.show);  //false
     此时可以看出构造函数的多次创建会产生多个相同函数,造成冗余太多。
     利用原型prototype解决。首先观察prototype是什么东西
     function Fn(){}
     console.log(Fn.prototype);
     //constructor表示当前的函数属于谁
     //__proto__ == [[prototype]],书面用语,表示原型指针
     var fn1 = new Fn();
     var fn2 = new Fn();
     Fn.prototype.show = function(){
      alert(1);
     }
     console.log(fn1.show==fn2.show);  //ture
    //前端全栈学习交流圈:866109386
    //面向1-3经验年前端开发人员
    //帮助突破技术瓶颈,提升思维能力
    

    此时,任何一个对象的原型上都有了show方法,由此得出,构造函数Fn.prototype身上的添加的方法,相当于添加到了所有的Fn身上。

    二、call和applay继承

    function Father(skill){
      this.skill = skill;
      this.show = function(){
       alert("我会"+this.skill);
      }
     }
     var father = new Father("绝世木匠");
     function Son(abc){
      //这里的this指向函数Son的实例化对象
      //将Father里面的this改变成指向Son的实例化对象,当相遇将father里面所有的属性和方法都复制到了son身上
      //Father.call(this,abc);//继承结束,call适合固定参数的继承
      //Father.apply(this,arguments);//继承结束,apply适合不定参数的继承
     }
     father.show()
     var son = new Son("一般木匠");
     son.show();
    

    三、原型链继承(demo)

    这个的么实现一个一个简单的拖拽,a->b的一个继承。把a的功能继承给b。

    HTML:

    <div id="drag1"></div>
    <div id="drag2"></div>
    

    CSS:

    *{margin: 0;padding: 0;}
     #drag1{width: 100px;height: 100px;background: red;position: absolute;}
     #drag2{width: 100px;height: 100px;background: black;position: absolute;left: 500px;}
    

    JS:

    function Drag(){}
     Drag.prototype={
      constructor:Drag,
      init:function(id){
       this.ele=document.getElementById(id);
       this.cliW=document.documentElement.clientWidth||document.body.clientWidth;
       this.cliH=document.documentElement.clientHeight||document.body.clientHeight;
       var that=this;
       this.ele.onmousedown=function(e){
        var e=event||window.event;
        that.disX=e.offsetX;
        that.disY=e.offsetY;
        document.onmousemove=function(e){
         var e=event||window.event;
         that.move(e);
        }
        that.ele.onmouseup=function(){
         document.onmousemove=null;
        }
       }  
      },
      move:function(e){
       this.x=e.clientX-this.disX;
       this.y=e.clientY-this.disY;
       this.x=this.x<0?this.x=0:this.x;
       this.y=this.y<0?this.y=0:this.y;
       this.x=this.x>this.cliW-this.ele.offsetWidth?this.x=this.cliW-this.ele.offsetWidth:this.x;
       this.y=this.y>this.cliH-this.ele.offsetHeight?this.y=this.cliH-this.ele.offsetHeight:this.y;
       this.ele.style.left=this.x+'px';
       this.ele.style.top=this.y+'px';
      }
     }
     new Drag().init('drag1')
     function ChidrenDrag(){}
     ChidrenDrag.prototype=new Drag()
     new ChidrenDrag().init('drag2')
    //前端全栈学习交流圈:866109386
    //面向1-3经验年前端开发人员
    //帮助突破技术瓶颈,提升思维能力
    

    四、混合继承

    function Father(skill,id){
      this.skill = skill;
      this.id = id;
     }
     Father.prototype.show = function(){
      alert("我是father,这是我的技能"+this.skill);
     }
     function Son(){
      Father.apply(this,arguments);
     }
     //如果不做son的原型即成father的原型,此时会报错:son.show is not a function
     Son.prototype = Father.prototype;
     //因为,如果不让son的原型等于father的原型,son使用apply是继承不到原型上的方法
     //但这是一种错误的原型继承示例,如果使用这种方式,会导致修改son原型上的show方法时,会把father身上的show也修改
     //内存的堆和栈机制
     Son.prototype.show = function(){
      alert("我是son,这是我的技能"+this.skill);
     }
     var father = new Father("专家级铁匠","father");
     var son = new Son("熟练级铁匠","son");
     father.show();
     son.show();
     上面的示例应该修改成以下形式:
     以上红色的代码应改成:
     for(var i in Father.prototype){
      Son.prototype[i] = Father.prototype[i];
     }
     //遍历father的原型身上的所有方法,依次拷贝给son的原型,这种方式称为深拷贝
     这种继承方式叫做混合继承,用到了for-in继承,cell和apple继承。
    

    五、Es6的class继承(demo)

    这个demo的功能和原型链继承的demo功能一样,a->b的继承

    HTML:

    <div id="drag1"></div>
    <div id="drag2"></div>
    

    CSS:

    *{margin: 0;padding: 0;}
    #drag1{width: 100px;height: 100px;background: red;position: absolute;}
    #drag2{width: 100px;height: 100px;background: black;position: absolute;left: 500px;}
    

    JS:

    class Drag{
       constructor(id){
        this.ele=document.getElementById(id);
        this.init();
       };
       init(){
        var that=this;
        this.ele.onmousedown=function(e){
         var e=event||window.event;
         that.disX=e.offsetX;
         that.disY=e.offsetY;
         document.onmousemove=function(e){
          var e=event||window.event;
          that.move(e);
         }
         that.ele.onmouseup=function(){
          document.onmousemove=null;
          that.ele.onmouseup=null;
         }//前端全栈学习交流圈:866109386
        }//面向1-3经验年前端开发人员
       };//帮助突破技术瓶颈,提升思维能力
       move(e){
        this.ele.style.left=e.clientX-this.disX+"px";
        this.ele.style.top=e.clientY-this.disY+"px";
       }
      }
      new Drag("drag1");
      class ExtendsDrag extends Drag{
       constructor(id){
        super(id);
       }
      }
      new ExtendsDrag("drag2")
    

    相关文章

      网友评论

        本文标题:JavaScript中的继承及实现代码

        本文链接:https://www.haomeiwen.com/subject/xrcnhqtx.html