第一步
解說(shuō):
先說(shuō)構(gòu)造函數(shù)(1),咱們只要new一下就能得到實(shí)例對(duì)象(2)
構(gòu)造函數(shù)(1)如何訪問(wèn)到原型(3),很簡(jiǎn)單通過(guò).prototype
通過(guò)實(shí)例對(duì)象(2),我們?nèi)绾卧L問(wèn),通過(guò)對(duì)象.__proto__
方式雖然不同已维,但是我們拿到的都是同一個(gè)對(duì)象
代碼演示:
function Person(userName, age) {
this.userName = userName
this.age = age
}
var p1 = new Person('豬八戒', 18)
// 這兩個(gè)相等返回true
console.log(Person.prototype)
console.log(p1.__proto__)
console.log(Person.prototype === p1.__proto__) // true
第二步
圖解
prototype(3)本身也是一個(gè)對(duì)象,既然也是一個(gè)對(duì)象已日,那么這個(gè)對(duì)象就應(yīng)該有它自己的構(gòu)造函數(shù)(4)垛耳,因?yàn)樗彩怯蓸?gòu)造函數(shù)生成的。
那也就是說(shuō)它也能訪問(wèn)到自己的原型(5)飘千。
這就是JS中最基本的繼承機(jī)制堂鲜!
代碼演示:
function Person() {
}
Person.prototype = new Object()
new Person().toString() // 從原型上繼承過(guò)來(lái)的
/*
* 我寫了這樣一個(gè)函數(shù),大家告訴我有沒(méi)有繼承發(fā)生护奈?
* 繼承其實(shí)現(xiàn)在已經(jīng)發(fā)生了缔莲,你雖然看不見(jiàn),但是瀏覽器已經(jīng)幫我們做過(guò)了 Person.prototype = new Object() 這句話我雖然不用寫霉旗,但是瀏覽器會(huì)幫我們自動(dòng)添加的
*
* 一上來(lái)就new Person().toString()痴奏,toString()方法哪來(lái)的想過(guò)沒(méi)有?你在函數(shù)里寫什么厌秒?什么也沒(méi)有寫啊读拆,這個(gè)toString()繼承的不就是Object嗎
* 這個(gè)就是JS的默認(rèn)繼承(原型繼承)
* */
new Object() // 也是一個(gè)對(duì)象,它雖然現(xiàn)在是Person的原型鸵闪,可是它本身也是一個(gè)對(duì)象檐晕。所以說(shuō)這個(gè)原型對(duì)象是不是也該有自己的原型呢?
console.log(Person.prototype.__proto__ === Object.prototype) // true岛马, 因?yàn)镻erson.prototype 就是一個(gè) new Object() 的實(shí)例(Person.prototype = new Object())棉姐,我們開始也說(shuō)了實(shí)例對(duì)象通過(guò)__proto__訪問(wèn)屠列,通過(guò)構(gòu)造函數(shù)是通過(guò)prototype進(jìn)行訪問(wèn)啦逆,但是他們倆是同一個(gè)且他們是絕對(duì)等價(jià)的
第三步
圖解
Object的原型(5),這里依舊是一個(gè)對(duì)象笛洛,那么這里它的構(gòu)造函數(shù)是誰(shuí)夏志?
如果你找5的構(gòu)造函數(shù),它其實(shí)就是Object,也就是說(shuō)5這個(gè)對(duì)象也是new 了 一個(gè) Object 沟蔑,new出來(lái)的湿诊,還是它自己的實(shí)例。
所以如果你試圖在往下找原型瘦材,不好意思這邊就真的沒(méi)有了厅须,訪問(wèn)不到了,到達(dá)頂層了就會(huì)返回null食棕。
鏈條怎么產(chǎn)生的朗和?鏈條其實(shí)就是2 ->3 -> 5
當(dāng)你實(shí)例化var p1 = new Person()
后,訪問(wèn)p1.age
的時(shí)候會(huì)先從實(shí)例對(duì)象(2)里找看一下有沒(méi)有age這個(gè)屬性簿晓,如果沒(méi)有找到就沿著自己的原型鏈條眶拉,找到自己的原型(3)去里面看看有沒(méi)有age屬性,找了一圈沒(méi)發(fā)現(xiàn)憔儿,繼續(xù)沿著鏈條往上找在5中查找忆植,在哪里找到了就斷開了繼續(xù)查找。如果沒(méi)有找到就返回null