溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JavaScript原型繼承機(jī)制原理

發(fā)布時(shí)間:2021-08-12 17:41:13 來(lái)源:億速云 閱讀:136 作者:chen 欄目:開發(fā)技術(shù)

本篇內(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ī)制。

一、typeof 和 instanceof

       在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)不合理。

1、typeof

<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

2、instanceof

實(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è)案例:

(1)案例一

                                                                 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ì)了。

二、prototype和{Prototype}(即__proto__)

        在Js中有兩個(gè)頂級(jí)上司,或者說(shuō)頂級(jí)公民:Function.prototypeObject.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í)用文章!

向AI問一下細(xì)節(jié)

免責(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)容。

AI