prototype 與 __proto__區別

admin發表於2018-11-23

關於prototype原型方面的問題一直都是初學者的一道門檻。

可能需要花費更多一點的精力才能深刻掌握,從而應用到開發中。

之所以比較難於理解,可能有如下兩方面原因:

(1).概念確實要花費精力才能掌握,並不相識let或者var宣告變數這種如此直白簡單。

(2).與標準面嚮物件語言的繼承機制迥然不認同,比如使用C#或者JAVA的開發人員可能會直接懵圈。

prototype與__proto__都與原型物件相關,它們都是指向原型物件的,所以給初學者帶來了不少困惑。

特別說明:

(1).__proto__屬性長相怪異,原本它是一個內部屬性,但是瀏覽器支援度良好,且ES2015將其標準化。

(2).不推薦使用__proto__屬性,而是使用Object.getPrototypeOf方法與Object.setPrototypeOf方法替代。

首先看一段程式碼例項:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
function Antzone(age){
  this.age=age
}
let ant=new Antzone(6);
console.log(ant.__proto__===Antzone.prototype);

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201811/23/225048bm0mmle243esrv31.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

可以看到prototype 與 __proto__指向同一個物件,也就是說物件例項的__proto__屬性指向建構函式的原型物件。

現在兩個屬性的主要不同點出來了,它們所屬物件的身份不相同:

(1).prototype屬於建構函式,指向建構函式的原型物件。

(2).__proto__屬於建構函式所建立的原型物件,同樣指向建構函式原型物件。

到這裡,不少朋友可能產生這樣的疑問,既然__proto__屬於物件例項,為什麼建構函式具有此屬性呢。

這是因為同一件事物可能擔負多個角色,比如一個男人是他兒子的父親,也是自己父親的兒子。

function函式雖然可以構造物件例項,但它自身也是Function建構函式的例項。

所以建構函式同時具有prototype與__proto__屬性就不足為奇了。

prototype 與 __proto__實現繼承:

利用建構函式建立ant物件例項,如果要訪問屬性p,會按照如下流程進行:

(1).首先會在物件例項ant自身開始查詢。

(2).如果沒有找到,那麼會在__proto__屬性指向的物件中查詢,也就是在建構函式原型物件中查詢。

(3).如果建構函式原型物件中也沒有,那麼再去原型物件__proto__指向的物件中查詢。

(4).上面其實就是JavaScript原型鏈繼承。

相關閱讀:

(1).prototype屬性參閱JavaScript prototype 原型一章節。

(2).__proto__屬性參閱__proto__屬性一章節。

相關文章