什么是Javascript原型鏈?
在JavaScript中,每個實例對象(object)都有一個私有屬性(__proto__)指向它的構(gòu)造函數(shù)的原型對象(prototype ),該原型對象也有一個私有屬性(__proto__)指向該原型對象的原型對象(prototype),層層向上直到一個對象的原型對象為 null。null 沒有原型,并作為這個原型鏈中的最后一個環(huán)節(jié)。
原型鏈的作用
JavaScript 對象有一個指向一個原型對象的鏈(原型鏈)。當(dāng)試圖訪問一個對象的屬性時,它不僅僅在該對象上搜尋,還會搜尋該對象的原型,以及該對象的原型的原型,依次層層向上搜索,直到找到一個名字匹配的屬性或到達原型鏈的末尾。
代碼圖例
/**
* 我們先寫一個構(gòu)造函數(shù),并通過該構(gòu)造函數(shù)得到一個實例對象
*/
// 構(gòu)造函數(shù)Person
function Person(job) {
this.job = job;
this.habit = ["eat", "drink", "sleep"];
}
// 新增方法
Person.prototype.printHabit = function () {
console.log(this.habit);
};
Person.prototype.printJob = function () {
console.log(this.job);
};
// 通過new來實例化一個person對象
const person = new Person("people");
接下來我門開始解析概念:
每個實例對象(object)都有一個私有屬性(__proto__)
我們打印一下這個person對象
console.log(person);

通過上圖我們可以看到person對象具有了 habit 、job 兩個屬性,以及它的私有屬性__proto__,這個私有屬性指向了一個Object,根據(jù)概念,實例都有一個私有屬性__proto__。
ps:這個Object實際上就是person的構(gòu)造函數(shù)的原型對象,接下來我們看下一句:
每個實例對象(object)都有一個私有屬性(__proto__)指向它的構(gòu)造函數(shù)的原型對象(prototype )
我們打印一下person實例的__proto__
console.log(person.__proto__)

通過上圖可以看到這個對象具有兩個方法:printhabit、printJob,這兩個方法其實就是我們剛才代碼中寫在Person的prototype上的方法,現(xiàn)在大致就可以得出,person的私有屬性__proto__指向它的構(gòu)造函數(shù)Person的prototype。我們通過代碼再來驗證下實例person的__proto__是不是指向Person的prototype
console.log(person.__proto__ === Person.prototype)

從驗證結(jié)果可以看出實例person的__proto__是指向了Person的prototype
在構(gòu)造函數(shù)Person的原型對象中又一個construtor屬性,這個屬性是指向構(gòu)造函數(shù)Person的,我們通過代碼驗證一下
console.log(Person.prototype.constructor === Person)

通過上面一系列的驗證結(jié)果我們可以得到以下結(jié)論關(guān)系:
構(gòu)造函數(shù)Person通過new來實例化對象person,實例person的私有屬性__proto__和構(gòu)造函數(shù)Person的prototype指向同一個對象,這個對象就是構(gòu)造函數(shù)Person的原型對象,而原型對象的constructor又指向了該原型對象的構(gòu)造函數(shù)Person
關(guān)系圖如下:

以上就是一層原型鏈的推倒結(jié)論,感興趣的同學(xué)可以接著往下推導(dǎo),到最后的關(guān)系圖如下:
