為什么要理解原型和原型鏈,因?yàn)橛欣谖覀兝斫夂蛯?shí)現(xiàn) JS對(duì)象繼承薇溃。
__
proto__
-
__proto__
是什么When a constructor creates an object, that object implicitly references the constructor’s prototype property for the purpose of resolving property references. -----------ES6 文檔
JS 中創(chuàng)建出來(lái)的對(duì)象都會(huì)有一個(gè)隱式引用,它指向的是構(gòu)造器的
prototype
航夺。這個(gè)隱式引用就是對(duì)象內(nèi)部[[prototype]]奥邮,通常情況下我們是無(wú)法訪(fǎng)問(wèn)到這個(gè)屬性的,但是可以通過(guò)瀏覽器實(shí)現(xiàn)的__proto__
屬性去訪(fǎng)問(wèn)它枫弟,每一個(gè)對(duì)象都會(huì)有一個(gè)__proto__
屬性邢享。雖然可以通過(guò)__proto__
訪(fǎng)問(wèn)到[[prototype]],但是ECMAScript 不建議通過(guò)__proto__
去修改內(nèi)部[[prototype]] 屬性淡诗,因?yàn)檫@是個(gè)影響性能的操作骇塘。 __proto__
指向哪里
__proto__
是一個(gè)引用而且指向constructor 的prototype
prototype
-
prototype 是什么伊履?
只有函數(shù)才會(huì)有prototype
屬性。當(dāng)你創(chuàng)建一個(gè)函數(shù)時(shí)款违,它的prototype
會(huì)初始化為一個(gè)"空對(duì)象" (里面含有一個(gè)constructor
屬性唐瀑,它是不可枚舉屬性,近似認(rèn)為"空對(duì)象")奠货,之后就可以往里面增加屬性或方法介褥。prototype
主要用于存儲(chǔ)公用的方法和屬性,然后等待實(shí)例的__proto__
來(lái)指向它递惋。zhgzhg
原型鏈
-
空對(duì)象toString() 方法從何而來(lái)柔滔?
zhg
其實(shí)上面的代碼,做了下面幾件事:- 看看 obj 對(duì)象本身有沒(méi)有 toString 屬性萍虽。沒(méi)有就走到下一步睛廊。
- 看看 obj.
__
proto__
對(duì)象有沒(méi)有 toString 屬性,發(fā)現(xiàn) obj.__
proto__
有 toString 屬性杉编,于是找到了超全。所以 obj.toString 實(shí)際上就是第 2 步中找到的 obj.__
proto__
.toString。
------知乎專(zhuān)欄:什么是 JS 原型鏈邓馒?
由于
obj.__proto__
===Object.prototype
所以obj 還可以調(diào)用Object.prototype
中其它的屬性嘶朱。可是如果obj 調(diào)用的屬性在Object.prototype
上也沒(méi)有呢光酣?那么它就會(huì)在Object.prototype.__proto__
中尋找疏遏,又Object.prototype.__proto__
等同于obj.__proto__.__proto__
。所以如果在obj.__proto__.__proto__
上也沒(méi)有找到救军,他會(huì)繼續(xù)在obj.__proto__.__proto__.__proto__
上尋找财异,直到他找到屬性或者 .__proto__
為null 。如
obj.__proto__.__proto__. . . . . .
這樣由.__proto__
組成的鏈條唱遭,就是原型鏈戳寸。 通過(guò)原型鏈,實(shí)例可以得到自身沒(méi)有但原型鏈上存在的方法或?qū)傩浴?/p>其實(shí)
instanceof
就是利用原型鏈的特點(diǎn)來(lái)工作的拷泽。比如判斷obj 是否是Object 的實(shí)例(obj instanceof Object
)疫鹊,相當(dāng)于判斷obj.__proto__.__proto__. . .
是否等于Object.prototype
。 -
原型鏈的重點(diǎn)
__proto__
和prototype
之間的相互關(guān)系司致,構(gòu)成了JS 的原型鏈订晌。個(gè)人認(rèn)為掌握原型鏈,必須記住下面三句話(huà):- 某對(duì)象的
__
proto__
===== 它構(gòu)造函數(shù)的prototype - Object.prototype.
__
proto__
===== null - Function.prototype.
__
proto__
===== Object.prototype
- 某對(duì)象的
-
Function.prototype 和Obect.prototype
Function
是所有函數(shù)的原型(Function.prototype
除外)蚌吸。它是對(duì)象同時(shí)又是函數(shù),所以它有__proto__
和prototype
屬性砌庄。利用上面三句話(huà)的第一句某對(duì)象的
proto
===== 它構(gòu)造函數(shù)的prototype
,可以得到:Function.__proto__
===Function.prototype
羹唠。而Object
奕枢、Number
、String
佩微、Array
缝彬、Boolean
等構(gòu)造函數(shù)情況同Function
相差不大,所以它們都是繼承自Function
哺眯,它們的__proto__
會(huì)等于Function.prototype
谷浅。Function.prototype
繼承自哪里?typeof Function.prototype //"function" Function.prototype instanceof Function //false Function.prototype.prototype //undefined
由上面可以得到:
Function.prototype
是一個(gè)沒(méi)有prototype
屬性的函數(shù)奶卓,它不是繼承自Function
一疯。Function.prototype instanceof Object //true Function.prototype.__protot__ === Object.prototype //true
得到
Function.prototype
是繼承自O(shè)bject 的。
Object.prototype
繼承自哪里?typeof Object.prototype //"object" Object.prototype instanceof Object //false Object.prototype.__proto__ === null
得出
Object.prototype
是一個(gè)對(duì)象夺姑,但他不是繼承自Object
對(duì)象墩邀,也不是繼承自null,它是對(duì)象繼承的最頂端盏浙。 總結(jié)
- 原型圖
鏈接
1眉睹、從proto和prototype來(lái)深入理解JS對(duì)象和原型鏈
2、js中proto和prototype的區(qū)別和關(guān)系废膘? ---蘇墨橘的回答
3竹海、什么是 JS 原型鏈?