首先另患,我沒需要了解清楚一下知識:
1.在js中囊陡,萬物皆對象芳绩,方法(Function)是對象,方法的原型Function.prototype也是對象撞反,所以他們都會擁有對象共有的特點proto妥色,可以稱之為隱式類型,一個對象的隱式類型指向構(gòu)造該對象的構(gòu)造函數(shù)的原型遏片,這也保證了實例能夠訪問在構(gòu)造函數(shù)原型中定義的方法和屬性
2.方法(Function)是一個特殊的對象嘹害,除了和其它對象一樣,都擁有proto的隱式屬性吮便,還有自己的特殊屬性原型屬性(prototype)笔呀,這是屬性是一個指針,指向一個對象髓需,指向的這個對象包含有所有實例共享的屬性和方法许师,這個對象就是原型對象。原型對象也有一個屬性僚匆,叫做constructor微渠,這個屬性也有一個指針,指向原構(gòu)造函數(shù)咧擂。
接下來逞盆,分別了解prototype和proto是什么:
1.prototype:每一個函數(shù)在創(chuàng)建之后,都會有一個prototype的屬性松申,指向構(gòu)造函數(shù)的原型對象云芦,用于訪問函數(shù)的原型對象。
1.proto:js中的任意對象都有一個內(nèi)置屬性[[prototype]]贸桶,es5之前沒有標(biāo)準(zhǔn)方法訪問此屬性舅逸,但是大部分瀏覽器都是用proto來訪問,ed5中有了對于這個內(nèi)置屬性標(biāo)準(zhǔn)的Get方法Object.getPrototypeOf()刨啸。(用于訪問對象實例的原型對象)
代碼示例:
function Test(){}
const test = new Test()
test._proto_ === Test.prototype //true
test的proto指向它的實例的原型對象堡赔,后者也是指向它的原型對象,構(gòu)造函數(shù)擁有prototype屬性设联,對象實例擁有proto屬性善已,它們都是用來訪問實例對象的。
函數(shù)有點特別离例,它不僅是個函數(shù)换团,還是個對象。所以它也有proto屬性宫蛆。
那么艘包,為什么會是這樣呢的猛?
因為函數(shù)是內(nèi)置構(gòu)造函數(shù)Function的實例
const test = new Function("function Test(){}")
test._proto_ === Function.prototype //true
所以函數(shù)也可以通過proto訪問它的對象。
由于prototype也是一個對象想虎,所以它也可以通過proto去訪問它的原型對象卦尊,對象的原型對象是Object.prototype
function Test(){}
Test.prototypr._proto_ === Object.prototype //true
換個角度看,其實Object其實也是一個內(nèi)置函數(shù)
const obj = new Object()
obj._proto_ === Object.prototype
為了防止無休止循環(huán)下去舌厨,所以O(shè)bject.proto指向null岂却,所以使用Object.create(null)創(chuàng)建的對象是沒有proto屬性的,也沒有prototype的屬性裙椭。
總結(jié)
prototype是構(gòu)造函數(shù)才有的躏哩,它指向的是當(dāng)前對象的原型對象,也成為顯示原型揉燃,用來實現(xiàn)原型的繼承以及屬性的共享扫尺。
所有的對象都有proto,構(gòu)造函數(shù)實例化對象的proto的指向與構(gòu)造函數(shù)prototype指向相同炊汤,也成為隱式原型正驻,構(gòu)成原型鏈。
在原型鏈中抢腐,我沒尋找obj中的x屬性拨拓,如果在自身沒有找到此屬性的話,就會向上尋找一直尋找到Object,prototype.proto的終點氓栈。
Object.create(null)創(chuàng)建對象沒有proto
方法是個特殊的對象,不僅有屬性proto還有屬性prototype婿着,prototype指向方法的原型對象授瘦。
經(jīng)典原型圖: