什麼是原型?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 是根據原型鏈來實現繼承的啦 在有不懂了 能夠看下面這個圖 這個圖要記下來
這個圖我也忘了 是從哪篇文章找到得了 我是由於看了那篇文章 才明白的原型鏈 。。。在這裏我感謝一下那篇文章的做者 還有圖借我用一下 哈哈。。。