📖摘要
本文主要深刻介紹了[[prototype]]
和prototype
這兩個屬性,順着這個思路講解了原型鏈的造成過程。函數
從一個很迷惑的經典題目開始。prototype
Object instanceof Function //true Function instanceof Object //true
首先,咱們要了解,這裏的Object
和Function
都是指JS中的內置函數對象。爲了講透它,咱們從兩個屬性入手,[[prototype]]
和prototype
。code
這兩個屬性都說是指向原型。那有什麼不一樣呢。對象
每個函數在建立以後都會擁有一個名爲prototype
的屬性,這個屬性指向該函數的原型對象。[[prototype]]
是任何對象都有的內部屬性。也就是,只有函數對象有prototype
屬性,而每一個對象都有[[prototype]]
屬性。blog
【這裏說明一下,因爲[[prototype]]
是內部屬性,因此ES5以前是不能夠直接訪問的,但Safari、Firefox和Chrome都支持一個屬性_prpto_
,能夠用它來訪問。從ES5後,新增了方法Object.getPrototypeOf()
能夠用來訪問這個內部屬性。】繼承
[[prototype]]
指向的建立這個對象的函數(也就是構造函數)的prototype
。圖片
function SuperType () { } function SubType () { } SubType.prototype = new SuperType(); //subType.prototype === SuperType var instance = new SubType(); //instance的構造函數是SubType console.log(Object.getPrototypeOf(instance)); //SuperType{}
咱們知道兩者的做用都是用來實現基於原型的繼承,但prototype
能夠用來實現屬性的共享,而[[prototype]]
主要是用來構成原型鏈。因此咱們平常所說的原型鏈其實這個原型指的是[[prptotype]]
的指向構成的鏈,而不是prototype
。仍是上面那個栗子,咱們用圖來表示一下其原型鏈和原型關係。
圖中,藍色線表示原型鏈指向,其中,實線是實例instance
的原型鏈,虛線其餘的[[prototype]]指向。黃色線是原型對象指向。原型鏈
SubType
來生成一個實例instance
的時候,其內部屬性[[prototype]]
指向其構造函數SubType
的原型對象SubType.prototype
。SubType
的原型對象手動更改爲了SuperType
的一個實例,因此其構造函數是SuperType
,[[prototype]]
指向SuperType.prototype
。new Object()
得來,因此SuperType.prototype
的[[prototype]]
指向Object.prototype
。Function.prototype
的幾條藍色虛線:內置的一些生成類型對象的函數,例如,Object|Number|Stirng|Array|Function
等,以及用function(){}
的方式建立的函數以及都至關於經過new Function()
得來,因此,其[[prototype]]
指向Function.prototype
。Function.prototype
指向Object.prototype
。這也是JS內置的,這也就是咱們常說的函數自己也是對象。你可能會問,那Object.prototype
的[[prototype]]
是什麼呢,不是全部對象都有[[prototype]]
麼,JS中規定,它的原型是null
。原型鏈到此爲止。get
還有一點須要注意的是,JS內在規定,Funtion.prototype
是一個函數。原型
console.log(typeof Object.prototype); //object console.log(typeof Function.prototype); //function
到如今,咱們距離開頭那個問題的答案只剩一步之遙。
instanceof的用法
instanceof運算符用於j檢測構造函數的prototype屬性是否出如今對象的原型鏈中的任何位置
這樣順着圖中原型鏈一找,不可貴到答案。