您好,登錄后才能下訂單哦!
本篇內容介紹了“JavaScript原型繼承機制原理”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
文章目錄
(1)案例一
JavaScript原型繼承機制
JavaScript并非一個純粹的面向的對象的語言,也沒有一個實際意義上的繼承機制。語言的設計者最初并未想實現繼承機制,但是后來還是實現了一個類似的機制——原型繼承機制。但實際上,這并非實際的繼承,我們來一一揭開JavaScript的偽繼承機制。
在JavaScript中,typeof是測試對象的類型,只會測試出對象屬于哪種內置類型,無法測試自定義類型。也就是所有自定義類型都會返回object。
而obj instanceof sometype(obj 指對象,sometype指的是類型),是測試obj的原型鏈中是否有sometype類型。所以通過錯誤的改變prototype的值會使得instanceof得出的結構不合理。
<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>
結果:
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
這說明元構造器的類型為:function
內建的普通構造器類型為:function
自定義普通構造器類型為:function
所有內置對象類型為:內置類型
所有自定義普通對象:object
實際就是測試實例是否有繼承基類的原型鏈,如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/>");
結果:
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/>");
結果:
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/>");
結果:
false true true [object Object]
下面我們就來具體分析這三個案例:
var Person = function(){};
這句具體發生了什么呢?我們用下面的偽代碼來解釋一下:生成了一個函數對象Person
{ this.prototype = {constructor:this}; //{}表示一個Object構造的空對象 var prototype = Function.prototype; //內部{Prototype}屬性,不能改變 this.__proto__ = prototype; //內部屬性的外部訪問方式, this.constructor = this; // 默認的,也是合理的值 }
var obj = new Person();
這句發生了什么呢?我們也用偽代碼來解釋一下:生成普通對象obj
{ var prototype = Person.prototype; this.__proto__ = prototype; this.constructor = Person; }
按此來說,在案例一中:
//function類型 Person.__proto__=== Function.prototype; //object類型, 默認情況下每個構造器內部都有一個Object的實例對象,供所有子類共享,這就是所有對象都默認繼承object的實例的原因 Person.prototype === obj.__proto__ ; //驗證每個自定義類型都默認繼承自一個Object實例object Person.prototype.__proto__ = Object.prototype; //每個對象的構造器為構造它的函數對象 Person.constructor === Function; Function.constructor === Function; //說明Function由自己構造,自舉性 obj.constructor === Person; //從中可以看出prototype告訴構造器,你構造的對象應該繼承誰 //__proto__可以告訴我們該對象繼承自誰。
其次我們可以看出:
//Function 的自舉性 Function.prototype === Function.prototype; Function.__proto__ === Function.prototype; Function.constructor === Function; //Object由Function構造 Object.prototype === Object.prototype; Object.__proto__ === Function.prototype; Object.constructor === Function; Function.prototype.__proto__ === Object.prototype; //說明Object.prototype是萬物之源
而obj對象呢,也有著這些特性,不過它是普通對象,沒有公開屬性prototype:
//普通對象特性 obj.__proto__ === Person.prototype; obj.constructor === Person;
我們再來看看Object.prototype:
//元對象 Object.prototype === Object.prototype; //對象的祖宗,根 Object.prototype.__proto__ === null; //祖先沒有祖先,單位了系統完備,其內部仍然有{Prototype}屬性,置為null,合理。 Object.prototype.constructor === Object; //祖先按理說是沒有構造器的,但為了說明祖先仍然屬于Object的實例,就這么做。
接著我們再看看Function.prototype:
//元構造器 Function.prototype === Function.prototype; //由Function構造出來的對象的原型 Function.prototype.__proto__ === Object.prototype; //對象Function.prototype的原型為Object.prototype Function.prototype.constructor === Function; //對象Function.prototype是由構造器Function構造的,實際上并非如此,但是為了Function.prototype的類型是Function也就這么設計了。
在Js中有兩個頂級上司,或者說頂級公民:Function.prototype 和Object.prototype。
1.一切都是對象
在Js中一切都是對象,而幾乎所有對象都由構造器產生。不過有一個例外,所有對象的基礎(元對象):Object.prototype,他不是由構造器產生,而是由Js引擎實現。它不同于java的Object——那是一個類,而Js中的Object.prototype僅僅是一個對象,它不能作為構造器。這來來講就好比西方人類最初也只有兩個人作為祖先——亞當和夏娃。但是在Js中只有一個沒有構造功能的Object.prototype那么如何基于這個原型來構造子對象呢,這就需要下面講到的元構造器——Function.prototype。
2.Object.prototype不是由構造器產生
3.Function.prototype由自己構造,但是卻是繼承自Object.prototype
4.繼承只是繼承對象,所謂對象A繼承自B,說明對象A維護者對象B的引用
5.函數對象中的__proto__才是指明該函數對象作為對象時繼承自誰,或者說維護了哪個對象的引用
6.函數對象中有個特別的特性prototype,這是普通對象所不具有的,這是函數對象作為構造器時的特性,它指明了該構造器作為”偽類“時的內部數據結構,他是一個引用類型。由該構造器構造出來的對象都維護著prototype所引用的對象的引用
“JavaScript原型繼承機制原理”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。