JS基礎知識複習---原型鏈

最近在複習js的基礎知識,今天準備學習的是js原型鏈,那在介紹js原型鏈之前先看一段代碼。

function Person() {
} // 一個構造函數

let person1 = new Person();
let person2 = new Person();

Person.prototype.name = 'koala';

console.log(person1.name) // koala;	
console.log(person2.name) // koala;	

如上,有一個構造函數Person,並new了兩個實例對象,person1、person2;
在構造函數的實例原型上增加了name屬性,則構造函數生成的兩個實例,也會找到name的屬性,並且值爲koala。

prototype
每個構造函數都會有prototype屬性,它指向的是構造函數創建的實例的實例原型,在上面的例子中,也就是person1、person2的原型。如何理解實例原型呢?每一個javascript對象(null除外)的生成,都會產生與之關聯的一個另一個對象,這個對象就是原型,每一個對象都會從原型"繼承"屬性。

需要注意的是proptotype是隻有函數纔會有的屬性

用一張圖直觀的表示構造函數和實例原型的關係:

prototype
Person構造函數
Person.proptotype

在瞭解了構造函數和實例原型的關係後,我們來想想,實例和實例原型的關係如何關聯呢?

_ proto_
每個對象都會有__proto__屬性,對象的__proto__屬性指向對象的實例原型。

prototype
生成
__proto__
Person構造函數
Person.proptotype
person實例

需要注意的是__proto__是隻有對象纔會有的屬性

function Person(){}
let person1 = new Person();

console.log(person1.__propto__ === Person.prototype) // true

在瞭解了實例和實例原型之間的聯繫後,我們思考一下,實例原型可以指回實例和構造函數嗎?因爲構造函數會生成多個實例,所以沒有實例原型可以指回實例,但是實例原型可以通過constructor屬性指回構造函數。

constructor
每一個實例原型都有一個constructor屬性指向與之關聯的構造函數。

function Person() {};
console.log(Person.prototype.constructor === Person); // true;

//介紹一個es5的方法Object.getPrototypeOf(obj):獲取obj對象的原型。

console.log(Object.getProttypeOf(person) === Person.proptotye) // true;
prototype
constructor
生成
__proto__
Person構造函數
Person.proptotype
person實例

以上內容介紹了實例,實例原型,構造函數之間的關係。接下來將爲大家介紹一下實例和實例原型之間的聯繫。

function Person(){}
let person1 = new Person();
Person.prototype.name = 'koala2';
person1.name = 'koala1';
console.log(person1.name); // koala1;
delete person1.name;
console.log(person1.name); // koala2;

在這個例子中,實例person1的屬性被刪除後,實例就會向它的原型去查找屬性,原型也是對象,既然是對象那麼原型也有原型,如果在原型上查找不到屬性,就會向原型的原型上查找,如法炮製,那原型的原型是什麼呢?

原型的原型
在前面,我們已經講了原型也是一個對象,既然是對象,我們就可以用最原始的方式創建它:

let obj = new Object();

其實原型對象就是通過 Object 構造函數生成的,那 Object.prototype 的原型呢?

null
我們可以打印:
console.log(Object.prototype.proto === null) // true
然而 null 究竟代表了什麼呢?
null 表示“沒有對象”,即該處不應該有值。
所以 Object.prototype.proto 的值爲 null 跟 Object.prototype 沒有原型,其實表達了一個意思。
所以查找屬性的時候查到 Object.prototype 就可以停止查找了。
最後一張關係圖也可以更新爲:

prototype
constructor
__proto__
constructor
prototype
__proto__
生成
__proto__
Person構造函數
Person.proptotype
Object.prototype
Object構造函數
null
person實例
發佈了17 篇原創文章 · 獲贊 10 · 訪問量 5049
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章