1. 程式人生 > >建構函式、例項、原型、原型鏈之間的關係

建構函式、例項、原型、原型鏈之間的關係

1、建構函式是什麼

        所謂的建構函式其實就是一個普通的函式前面加了new運算子,其實質也是一個函式,所以建構函式都有函式的prototype屬性。

2、例項是什麼

        例項就是通過建構函式創建出來的物件。

                    var M = function () {
			this.name = 'Jane'
                    } 
                    var obj = new M()

3、原型是什麼

        原型指的就是原型物件,至於是誰的原型物件,需要靠函式的prototype屬性和例項的__proto__屬性來區別。

4、原型鏈是什麼

        指從一個例項物件開始往上找,這個例項物件的__proto__屬性所指向的則是這個例項物件的原型物件,如果用obj表示這個例項,則原型物件表示為obj.__proto__。同時,這個原型物件顧名思義也是一個物件,而且它也有上一級的原型物件,相對於上一級原型物件而言,它也是一個例項物件,那麼它也擁有__proto__屬性,它的__proto__屬性也指向它的原型物件,後面也以此類推,一直到Object.prototype這個原型為止,Object.prototype為原型鏈的末尾點。


        通過上圖第一個紅色框出來的屬性可看到,obj通過呼叫兩次__proto__屬性就已經到達Object,Object是一個建構函式,Object擁有屬性prototype,可以指向它的原型。第三次呼叫的時候已經返回空,表明Object.prototype為原型鏈的末端。

5、建構函式與例項之間的關係

        如前所述,例項是通過建構函式建立

6、建構函式與原型(物件)之間的關係

        建構函式通過其屬性prototype去尋找它關聯的原型,如果用M表示建構函式,M.prototype所指的就是它關聯的原型物件,而原型物件可以通過構造器constructor來尋找與自身關聯的建構函式,所以就有M.prototype.conctructor===M。


7、例項與原型之間的關係

        其實在前面的原型鏈解釋那裡就說了例項與原型之間的關係,但是這裡也還是贅述一下,因為等下5、6、7點結合來談。很簡單,就一句話可以概括,例項通過它的__proto__屬性去尋找它關聯的原型物件,所以原型物件又可以表示為obj.__proto__。若用obj.__proto__=obj關聯的原型物件,而結合第6點,M.prototype=M關聯的原型物件,又因為第5點,obj是M建立的,所以obj關聯的物件就是M關聯的物件(其實這裡可用instanceof來判斷例項與建構函式是否引用同一地址,事實是引用了同一地址。後面第9點會講到instanceof),最終,obj.__proto__===M.prototype為true。這在控制檯可驗證。


8、原型物件上的屬性、方法可以被例項共享,原因看程式碼演示

                var M = function (name) {
			this.name = name
		} 
		//建構函式原型物件上定義屬性和方法
		M.prototype.country = 'US'
		M.prototype.say=function(){
			console.log("hhh")
		}
		var obj1 = new M('Jane')
		var obj2 = new M('Tom')

        兩個同一建構函式的不同例項,可以呼叫原型物件上的屬性和方法,值都一樣,所以控制檯返回true。

9、instanceof的原理

        首先,通過instanceof能做什麼呢?instanceof可以判斷例項物件的__proto__屬性是否與建構函式的prototype屬性指向同一地址,是的話返回true,否則fasle。
        而原型物件上還有上一級的原型物件,上一級原型物件也有對應的建構函式,事實上,例項的__proto__屬性與在原型鏈上的所有建構函式的prototype屬性都指向同一個地址,所以有如下的結果。


        需要注意的是,雖然instanceof判斷的是例項屬性與函式屬性的指向問題,但是在使用的時候要注意instanceof 左邊是例項,右邊是建構函式。

        一句話概括就是用例項物件來判斷建構函式與原型物件的建構函式。

10、構造器constructor

        但是想找到與例項直接相關聯的建構函式就得用構造器constructor了。使用方法是先通過例項的__proto__屬性找到原型物件,再通過原型物件的屬性constructor來確定建構函式。


end