首先,結合以前的一篇博客js對象(一)——建立對象開頭,爲了理解對象,拋出了一系列比較繞的概念,即對象和函數的關係,搞清楚了這個問題,可能纔算真正理解了什麼是對象,什麼是函數。
仍是先看一些說法和描述:javascript
JavaScript中,一切都是對象,函數也是對象,數組也是對象,可是數組是對象的子集。
函數其實是對象,並且與其餘引用類型同樣具備屬性和方法,因爲函數是對象,所以函數名實際上也是一個指向函數對象的指針,不會與某個函數綁定。對象都是由函數建立的。
全部的對象都是由Object繼承而來,而Object對象倒是一個函數。html每個函數實際上都是Function類型的實例java
(在這裏看來,函數與對象之間有着說不清道不明的關係,函數是對象,對象又是又函數建立的,因此究竟是先有的函數仍是先有的對象,他們的原型或者說底層又有什麼關係呢😵?)segmentfault
藉助 prototype,__proto__,constructor這三個屬性,先從最簡單的開始提及😜:數組
經過原型模式建立對象,咱們接觸到了對象建立的機制,如圖:閉包
var o1 = new Object() var o2 = new Object()
接下來,再看另外一種構造函數創造機制:函數
function foo() {} var f1 = new foo() var f2 = new foo()
因爲一切對象(除Object.prototype)都繼承自Object,因此不難理解這裏最大的boss是Object.prototype,而構造它的原型對象是null,這不是證實了它就是最大的boss嗎?然而,並無那麼簡單,那麼,function()又是怎麼回事呢?繼續看:spa
咱們知道,一切函數都是Function的實例,而參考MDN-function ,咱們發現:prototype
Function 構造函數 建立一個新的Function對象。 在 JavaScript 中,
每一個函數實際上都是一個Function對象。全局的Function對象沒有本身的屬性和方法, 可是, 由於它自己也是函數,因此它也會經過原型鏈從Function.prototype上繼承部分屬性和方法。3d
這句話「Function從Function.prototype上繼承部分屬性和方法」,能夠解釋
Function.__proto__==Function.prototype
便可以說函數是由Function建立的,那麼Function由自身建立,因此Function.__proto__就指向了建立它的函數(也就是本身)的prototype。
最後,再來一張總的圖:
經過這張圖咱們就能夠輕鬆知道:
再總結一下,函數與對象的關係,看來,最大的boss仍是Object.prototype,由於從箭頭的進出來看,Object.prototype是沒有被誰創造出來的,而其餘對象都可以找到建立它的原型對象。
而上面所說的
對象都是由函數建立的。一切都是對象,函數也是對象
可能要上升到一個哲學的高度去理解了。但咱們卻要理解其底層的運行機制,也就是上面的總圖。掌握了那張圖,對接下來理解原型鏈,繼承很是有幫助(簡直就是必須😁)。
最後,歡迎你們圍觀指正!
參考:深刻理解javascript原型和閉包系列