JavaScript中的繼承及實現程式碼

wait.發表於2018-12-14

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")
複製程式碼

相關文章