老生常談JS中的繼承及實現(xiàn)代碼
JS雖然不像是JAVA那種強類型的語言,但也有著與JAVA類型的繼承屬性,那么JS中的繼承是如何實現(xiàn)的呢?
一、構(gòu)造函數(shù)繼承
在構(gòu)造函數(shù)中,同樣屬于兩個新創(chuàng)建的函數(shù),也是不相等的 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 此時可以看出構(gòu)造函數(shù)的多次創(chuàng)建會產(chǎn)生多個相同函數(shù),造成冗余太多。 利用原型prototype解決。首先觀察prototype是什么東西 function Fn(){} console.log(Fn.prototype); //constructor表示當(dāng)前的函數(shù)屬于誰 //__proto__ == [[prototype]],書面用語,表示原型指針 var fn1 = new Fn(); var fn2 = new Fn(); Fn.prototype.show = function(){ alert(1); } console.log(fn1.show==fn2.show); //ture 此時,任何一個對象的原型上都有了show方法,由此得出,構(gòu)造函數(shù)Fn.prototype身上的添加的方法,相當(dāng)于添加到了所有的Fn身上。
二、call和applay繼承
function Father(skill){ this.skill = skill; this.show = function(){ alert("我會"+this.skill); } } var father = new Father("絕世木匠"); function Son(abc){ //這里的this指向函數(shù)Son的實例化對象 //將Father里面的this改變成指向Son的實例化對象,當(dāng)相遇將father里面所有的屬性和方法都復(fù)制到了son身上 //Father.call(this,abc);//繼承結(jié)束,call適合固定參數(shù)的繼承 //Father.apply(this,arguments);//繼承結(jié)束,apply適合不定參數(shù)的繼承 } father.show() var son = new Son("一般木匠"); son.show();
三、原型鏈繼承(demo)
這個的么實現(xiàn)一個一個簡單的拖拽,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')
四、混合繼承
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是繼承不到原型上的方法 //但這是一種錯誤的原型繼承示例,如果使用這種方式,會導(dǎo)致修改son原型上的show方法時,會把father身上的show也修改 //內(nèi)存的堆和棧機制 Son.prototype.show = function(){ alert("我是son,這是我的技能"+this.skill); } var father = new Father("專家級鐵匠","father"); var son = new Son("熟練級鐵匠","son"); father.show(); son.show(); 上面的示例應(yīng)該修改成以下形式: 以上紅色的代碼應(yīng)改成: 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; } } }; 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")
我總結(jié)的這幾種繼承方法.兩個demo繼承的方法大家最好在編譯器上跑一下,看看。這樣才能更深刻的去理解。尤其是原型鏈的繼承,js作為一個面向?qū)ο蟮木幊陶Z言,還是很常用的。
總結(jié)
以上所述是小編給大家介紹的JS中的繼承及實現(xiàn)代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
JavaScript中undefined、null與NaN的區(qū)別
undefined、null和NaN都屬于javascript中的數(shù)據(jù)類型,本文主要介紹了 JavaScript中undefined、null與NaN的區(qū)別,具有一定的參考價值,感興趣的可以了解一下2023-09-09JS中使用gulp實現(xiàn)壓縮文件及瀏覽器熱加載功能
這篇文章主要介紹了JS中使用gulp實現(xiàn)壓縮文件及瀏覽器熱加載功能,需要的朋友可以參考下2017-07-07javascript 漢字轉(zhuǎn)拼音實現(xiàn)代碼
主要是提前定義了很多文字,這樣的方法不是很是,如果庫中沒有這個詞,是看不到相關(guān)信息的。2009-12-12淺談laytpl 模板空值顯示null的解決方法及簡單的js表達(dá)式
今天小編就為大家分享一篇淺談laytpl 模板空值顯示null的解決方法及簡單的js表達(dá)式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09