您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“JavaScript原型繼承機(jī)制原理”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
文章目錄
(1)案例一
JavaScript原型繼承機(jī)制
JavaScript并非一個(gè)純粹的面向的對(duì)象的語(yǔ)言,也沒有一個(gè)實(shí)際意義上的繼承機(jī)制。語(yǔ)言的設(shè)計(jì)者最初并未想實(shí)現(xiàn)繼承機(jī)制,但是后來(lái)還是實(shí)現(xiàn)了一個(gè)類似的機(jī)制——原型繼承機(jī)制。但實(shí)際上,這并非實(shí)際的繼承,我們來(lái)一一揭開JavaScript的偽繼承機(jī)制。
在JavaScript中,typeof是測(cè)試對(duì)象的類型,只會(huì)測(cè)試出對(duì)象屬于哪種內(nèi)置類型,無(wú)法測(cè)試自定義類型。也就是所有自定義類型都會(huì)返回object。
而obj instanceof sometype(obj 指對(duì)象,sometype指的是類型),是測(cè)試obj的原型鏈中是否有sometype類型。所以通過錯(cuò)誤的改變prototype的值會(huì)使得instanceof得出的結(jié)構(gòu)不合理。
<script> var num = 10; document.write("typeof num:"+typeof num+"<br/>"); var onum = Number(10); document.write("typeof onum:"+typeof onum+"<br/>"); var str = "1010"; document.write("typeof str:"+typeof str+"<br/>"); var ostr = String("1010"); document.write("typeof ostr:"+typeof ostr+"<br/>"); var bol = true; document.write("typeof bol:"+typeof bol+"<br/>"); var obol = true; document.write("typeof obol:"+typeof obol+"<br/>"); var dat = new Date(); document.write("typeof dat:"+typeof dat+"<br/>"); var func = new Function('x','y',"return x+y;"); document.write("typeof func:"+typeof func+"<br/>"); var myconstructor = function Person(){}; document.write("typeof myconstructor:"+typeof myconstructor+"<br/>"); var myobj = new myconstructor(); document.write("typeof myobj:"+typeof myobj+"<br/>"); </script>
結(jié)果:
typeof num:number typeof onum:number typeof str:string typeof ostr:string typeof bol:boolean typeof obol:boolean typeof dat:object typeof func:function typeof myconstructor:function typeof myobj:object
這說(shuō)明元構(gòu)造器的類型為:function
內(nèi)建的普通構(gòu)造器類型為:function
自定義普通構(gòu)造器類型為:function
所有內(nèi)置對(duì)象類型為:內(nèi)置類型
所有自定義普通對(duì)象:object
實(shí)際就是測(cè)試實(shí)例是否有繼承基類的原型鏈,如obj instanceof Type,若obj的原型鏈中Type則返回true,否則返回false。
//案例一 var Person = function(){}; var obj = new Person(); document.write((obj instanceof Person) +"<br/>"); document.write((obj instanceof Object) +"<br/>"); document.write(obj.__proto__ +"<br/>"); document.write(Person.constructor+"<br/>"); document.write(obj.constructor+"<br/>"); document.write((obj.constructor === Person)+"<br/>");
結(jié)果:
true true [object Object] function Function() { [native code]} function (){} true
//案例二 var other = function(){}; Person.prototype = new other(); document.write((obj instanceof Person) +"<br/>"); document.write((obj instanceof Object) +"<br/>"); document.write((obj instanceof other) +"<br/>"); document.write(obj.__proto__ +"<br/>"); document.write(obj.constructor+"<br/>");
結(jié)果:
false true false [object Object] function (){}
//案例三 obj.__proto__ = new other(); document.write((obj instanceof Person) +"<br/>"); document.write((obj instanceof Object) +"<br/>"); document.write((obj instanceof other) +"<br/>"); document.write(obj.__proto__ +"<br/>");
結(jié)果:
false true true [object Object]
下面我們就來(lái)具體分析這三個(gè)案例:
var Person = function(){};
這句具體發(fā)生了什么呢?我們用下面的偽代碼來(lái)解釋一下:生成了一個(gè)函數(shù)對(duì)象Person
{ this.prototype = {constructor:this}; //{}表示一個(gè)Object構(gòu)造的空對(duì)象 var prototype = Function.prototype; //內(nèi)部{Prototype}屬性,不能改變 this.__proto__ = prototype; //內(nèi)部屬性的外部訪問方式, this.constructor = this; // 默認(rèn)的,也是合理的值 }
var obj = new Person();
這句發(fā)生了什么呢?我們也用偽代碼來(lái)解釋一下:生成普通對(duì)象obj
{ var prototype = Person.prototype; this.__proto__ = prototype; this.constructor = Person; }
按此來(lái)說(shuō),在案例一中:
//function類型 Person.__proto__=== Function.prototype; //object類型, 默認(rèn)情況下每個(gè)構(gòu)造器內(nèi)部都有一個(gè)Object的實(shí)例對(duì)象,供所有子類共享,這就是所有對(duì)象都默認(rèn)繼承object的實(shí)例的原因 Person.prototype === obj.__proto__ ; //驗(yàn)證每個(gè)自定義類型都默認(rèn)繼承自一個(gè)Object實(shí)例object Person.prototype.__proto__ = Object.prototype; //每個(gè)對(duì)象的構(gòu)造器為構(gòu)造它的函數(shù)對(duì)象 Person.constructor === Function; Function.constructor === Function; //說(shuō)明Function由自己構(gòu)造,自舉性 obj.constructor === Person; //從中可以看出prototype告訴構(gòu)造器,你構(gòu)造的對(duì)象應(yīng)該繼承誰(shuí) //__proto__可以告訴我們?cè)搶?duì)象繼承自誰(shuí)。
其次我們可以看出:
//Function 的自舉性 Function.prototype === Function.prototype; Function.__proto__ === Function.prototype; Function.constructor === Function; //Object由Function構(gòu)造 Object.prototype === Object.prototype; Object.__proto__ === Function.prototype; Object.constructor === Function; Function.prototype.__proto__ === Object.prototype; //說(shuō)明Object.prototype是萬(wàn)物之源
而obj對(duì)象呢,也有著這些特性,不過它是普通對(duì)象,沒有公開屬性prototype:
//普通對(duì)象特性 obj.__proto__ === Person.prototype; obj.constructor === Person;
我們?cè)賮?lái)看看Object.prototype:
//元對(duì)象 Object.prototype === Object.prototype; //對(duì)象的祖宗,根 Object.prototype.__proto__ === null; //祖先沒有祖先,單位了系統(tǒng)完備,其內(nèi)部仍然有{Prototype}屬性,置為null,合理。 Object.prototype.constructor === Object; //祖先按理說(shuō)是沒有構(gòu)造器的,但為了說(shuō)明祖先仍然屬于Object的實(shí)例,就這么做。
接著我們?cè)倏纯?strong>Function.prototype:
//元構(gòu)造器 Function.prototype === Function.prototype; //由Function構(gòu)造出來(lái)的對(duì)象的原型 Function.prototype.__proto__ === Object.prototype; //對(duì)象Function.prototype的原型為Object.prototype Function.prototype.constructor === Function; //對(duì)象Function.prototype是由構(gòu)造器Function構(gòu)造的,實(shí)際上并非如此,但是為了Function.prototype的類型是Function也就這么設(shè)計(jì)了。
在Js中有兩個(gè)頂級(jí)上司,或者說(shuō)頂級(jí)公民:Function.prototype 和Object.prototype。
1.一切都是對(duì)象
在Js中一切都是對(duì)象,而幾乎所有對(duì)象都由構(gòu)造器產(chǎn)生。不過有一個(gè)例外,所有對(duì)象的基礎(chǔ)(元對(duì)象):Object.prototype,他不是由構(gòu)造器產(chǎn)生,而是由Js引擎實(shí)現(xiàn)。它不同于java的Object——那是一個(gè)類,而Js中的Object.prototype僅僅是一個(gè)對(duì)象,它不能作為構(gòu)造器。這來(lái)來(lái)講就好比西方人類最初也只有兩個(gè)人作為祖先——亞當(dāng)和夏娃。但是在Js中只有一個(gè)沒有構(gòu)造功能的Object.prototype那么如何基于這個(gè)原型來(lái)構(gòu)造子對(duì)象呢,這就需要下面講到的元構(gòu)造器——Function.prototype。
2.Object.prototype不是由構(gòu)造器產(chǎn)生
3.Function.prototype由自己構(gòu)造,但是卻是繼承自O(shè)bject.prototype
4.繼承只是繼承對(duì)象,所謂對(duì)象A繼承自B,說(shuō)明對(duì)象A維護(hù)者對(duì)象B的引用
5.函數(shù)對(duì)象中的__proto__才是指明該函數(shù)對(duì)象作為對(duì)象時(shí)繼承自誰(shuí),或者說(shuō)維護(hù)了哪個(gè)對(duì)象的引用
6.函數(shù)對(duì)象中有個(gè)特別的特性prototype,這是普通對(duì)象所不具有的,這是函數(shù)對(duì)象作為構(gòu)造器時(shí)的特性,它指明了該構(gòu)造器作為”偽類“時(shí)的內(nèi)部數(shù)據(jù)結(jié)構(gòu),他是一個(gè)引用類型。由該構(gòu)造器構(gòu)造出來(lái)的對(duì)象都維護(hù)著prototype所引用的對(duì)象的引用
“JavaScript原型繼承機(jī)制原理”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。