原型 、原型鏈和對象是怎么實現繼承的


什么是原型?

  聲明函數時 js會自動在你聲明的函數對象(js一切皆對象)上掛載一些方法和屬性  其中prototype屬性就是   原型(也稱為原型對象) 如下圖:

這個原型對象里面保存着 constructor 自己的函數體(也就是Pro.prototype.constructor)  看下圖就應該知道了吧 (Pro === Pro.prototype.constructor):

  這個原型對象里面還保存着 __proto__ 這個__proto__指向的就是Object.prototype(Pro.prototype.__proto__ === Object.prototype 它們兩個是一個“東西”)    里面保存着 所有,js自帶對象 Object下的方法如下圖:

 在對象使用方法(或屬性)時會查找自身原型(prototype)上的constructor有沒有我使用的這個方法(或屬性),如果沒有就去自身原型(prototype)的就像指向父級原型的__proto__查找

這里我說一下   prototype是自身原型       __proto__是父級原型(指向父級原型 也就是父級原型)

找到父級原型 上圖看到 父級原型上的constructor 下有很多方法。。。

我畫綠線的地方 是我其他篇文章《對象屬性類型》和《作用域和作用域鏈》介紹過的方法和屬性。。有興趣的可以去看一看

畫綠圈的地方是我接下來要說的  構造函數下有__proto__和prototype(最上面的圖顯示出了這兩個屬性) 我前面還提到了 constructor就是自身函數體

   用上圖的Pro函數來舉例子‘:

    Pro函數   可稱成為構造函數   也可稱為函數體  

    Pro.prototype.constructor存儲的是自身函數體 

    自身函數體.prototype === Pro.prototype

    自身函數體就是Pro函數

    所以這地方是一個無線循環

    Pro.prototype.constructor === 自身函數體 (上面說了 自身函數體就是Pro函數 所以)Pro.prototype.constructor.prototype  = = = Pro.prototype

  有點亂 但是我相信多想想能理解。。。

上圖還圈了一個屬性 __proto__  構造函數下有__proto__和prototype  這里我在解釋一邊  我上圖圈的那個__proto__就是 構造函數Pro(函數體),

Function和Object一樣都是js自帶函數對象

所以說是Pro.__proto__.上面只說了原型上的__proto__下面說說  構造函數的__proto__ 指向 所有構造函數的__proto__都指向Function.prototype,

  記住所有構造函數 包括他自己    Function函數

  

  直接輸出是看不到里面的東西的   但是也說明 有Function對象  然后我就想那new 出來一個實例  然后在     實例.__proto__    但是我發現new出來的實例居然有 prototype   (這里說明一下 除了Function的實例,其他對象的實例是沒有prototype的)

  

  這里 new Function 怎么會有prototype那    因為

new Function 也是創建函數的一種方式   (js規定的)        這時候就可以解釋為什么   Function.__proto__ === Function.prototype

 那么我們從Function上面得到什么了 畢竟所有構造函數的__proto__都指向 Function.prototype了

由於Function.prototype是無法直接訪問的  所以我們使用Object.getOwnPropertyNames方法獲取  Funciton.prototype上都有什么

上面也看到了。。。 Funciton.prototype有這些方法   證實一下  也證實上面說的,所有構造函數的__proto__都是Function.prototype

發現多一個 Symbol   這個是es6新增基礎類型  需要使用Object.getOwnPropertySymbols獲取

這個提一下  原型鏈頂端就是 Object.prototype.__proto__ = null   谷歌上控制台輸出的不明確   這里用IE 輸出一下   

上圖也是輸出 Object.prototype.constructor.__proto__

所有構造函數的__proto__都是Function.prototype

 那我為什么不知 直接 Object.__proto__

這就還是是想證明一下 Object.__proto__===Object.prototype.constructor.__proto__

上圖發現了  在谷歌上輸出 原型和IE上顯示輸出的方法不一樣   比如  get  __proto__ 、set  __proto__    和IE 的 __proto__ 

 

應該是谷歌瀏覽器 對js內置對象的一種修改  具體是怎么修改的和修改什么了  我也不清楚了。。。如果有知道的  請在下方留言謝謝!!!!

說的零零散散   最后需要總結一下。。。

原型就是 prototype   原型鏈 就是我在的原型上找不到的東西 我回去我的父級找 __proto__ 就是父級的指針     如下圖:

我創建了一個構造函數  Pro     

我又把Pro實例化  並且 賦值給了p   

p.toString()  實例對象p下是沒有toString的

p.__proto__  ===Pro.prototype 下constructor里面沒有 toString方法

然后就找Pro.prototype.__proto__  ===Object.prototype

Object.prototype.constructor下找到了toString方法   

所以才執行並且輸出了    有興趣可以百度查查  Object下的toString()方法怎么實現的。。。。

我為什么能使用toString()那  是因為我從 Object對象上繼承而來的   所以這里說一下 js 是根據原型鏈來實現繼承的啦    在有不懂了  可以看下面這個圖   這個圖要記下來  

  這個圖我也忘了 是從哪篇文章找到得了   我是因為看了那篇文章 才明白的原型鏈   。。。在這里我感謝一下那篇文章的作者   還有圖借我用一下  哈哈。。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM