【函數】:普通函數,類(所有的類:內置類,自己創建的類)
【對象】:普通對象,數組,正則,arguments…實例是對象類型的(除了基本類型的字面量創建的值),prototype的值也是對象類型的,函數也是對象類型的。
原型和原型鏈講解:
原型:一種管理機制
-
所有的函數都有一個
prototype
屬性(這也叫顯式原型,它也是一個普通的對象),瀏覽器默認爲它開啓一個堆內存。 -
瀏覽器默認爲它開啓一個的堆內存中,有一個
constructor
,存儲當前函數本身。 -
每一個實例都有一個
_ _ proto_ _
屬性(也叫隱式原型,它是一個普通的對象),指向當前實例所屬類的prototype
(如果不確定它是誰的實例,都是Object的實例)。 -
每一個實例都有一個
constructor
屬性,指向所屬類的constructor
,可以通過實例.constructor.prototype
找到原型,只是在開發中很少使用這個屬性,不多贅述。const str = new String("123"); str.constructor.prototype === String.prototype // true str.__proto__ === String.prototype // true
-
當試圖得到一個實例的屬性時,如果這個實例本身不存在這個屬性,那麼就會去它的
_ _ proto_ _
屬性(也就是它的構造函數的prototype
屬性)中去尋找。
原型鏈:一種查找機制
基於__proto__
向上查找的機制,有瀏覽器或者其他運行環境提供,不建議直接使用,建議使用Object.getPrototypeOf(實例)
替代。原本我們找到原型方法只能通過構造函數才能訪問,現在有了__proto__
,我們就可以直接從實例去訪問。
當我們操作實例的某個屬性或方法時,首先找自己空間中私有的屬性或方法。找到了,則查找結束,使用自己私有的即可。沒有找到,則通過__proto__
查找所屬類的原型prototype。如果還沒找到,則繼續通過__proto__
向上查找,一直到Object.prototype,如果還沒有,那操作的屬性或方法就不存在。
arr.length // 在arr的私有屬性中找到
arr.pop // 在arr的私有屬性中沒有找到,繼續通過arr.__proto__找到Array的原型prototype,從而查找到公共的pop方法
arr.__proto__.pop // 直接通過arr.__proto__找到Array的原型prototype,從而查找到公共的pop方法
arr.hasOwnProperty // 在arr的私有屬性中沒有找到,繼續通過arr.__proto__找到Array的原型prototype,也沒有找到,繼續通過Array.__proto__找到Object基類的原型prototype,從而找到hasOwnProperty