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

什麼是原型?es6

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

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

  這個原型對象裏面還保存着 __proto__ 這個__proto__指向的就是Object.prototype(Pro.prototype.__proto__ === Object.prototype 它們兩個是一個「東西」)    裏面保存着 全部,js自帶對象 Object下的方法以下圖:spa

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

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

找到父級原型 上圖看到 父級原型上的constructor 下有不少方法。。。對象

我畫綠線的地方 是我其餘篇文章《對象屬性類型》和《做用域和做用域鏈》介紹過的方法和屬性。。有興趣的能夠去看一看blog

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

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

    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 是根據原型鏈來實現繼承的啦    在有不懂了  能夠看下面這個圖   這個圖要記下來  

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

相關文章
相關標籤/搜索