1. 程式人生 > >最詳盡的 JS 原型與原型鏈終極詳解(二)

最詳盡的 JS 原型與原型鏈終極詳解(二)

小編推薦:Fundebug專注於JavaScript、微信小程式、微信小遊戲,Node.js和Java實時BUG監控。真的是一個很好用的bug監控費服務,眾多大佬公司都在使用。

四. __proto__

JS 在建立物件(不論是普通物件還是函式物件)的時候,都有一個叫做__proto__ 的內建屬性,用於指向建立它的建構函式的原型物件。
物件 person1 有一個 __proto__屬性,建立它的建構函式是 Person,建構函式的原型物件是 Person.prototype ,所以:
person1.__proto__ == Person.prototype

請看下圖:

 

《JavaScript 高階程式設計》的圖 6-1

根據上面這個連線圖,我們能得到:

Person.prototype.constructor == Person;
person1.__proto__ == Person.prototype;
person1.constructor == Person;

不過,要明確的真正重要的一點就是,這個連線存在於例項(person1)與建構函式(Person)的原型物件(Person.prototype)之間,而不是存在於例項(person1)與建構函式(Person)之間。

注意:因為絕大部分瀏覽器都支援__proto__屬性,所以它才被加入了 ES6 裡(ES5 部分瀏覽器也支援,但還不是標準)。

五. 構造器

熟悉 Javascript 的童鞋都知道,我們可以這樣建立一個物件:
var obj = {}
它等同於下面這樣:
var obj = new Object()

obj 是建構函式(Object)的一個例項。所以:
obj.constructor === Object
obj.__proto__ === Object.prototype

新物件 obj 是使用 new 操作符後跟一個建構函式來建立的。建構函式(Object)本身就是一個函式(就是上面說的函式物件),它和上面的建構函式 Person 差不多。只不過該函式是出於建立新物件的目的而定義的。所以不要被 Object 嚇倒。


同理,可以建立物件的構造器不僅僅有 Object,也可以是 Array,Date,Function等。
所以我們也可以建構函式來建立 Array、 Date、Function

var b = new Array();
b.constructor === Array;
b.__proto__ === Array.prototype;

var c = new Date(); 
c.constructor === Date;
c.__proto__ === Date.prototype;

var d = new Function();
d.constructor === Function;
d.__proto__ === Function.prototype;

這些構造器都是函式物件:

函式物件

六. 原型鏈

小測試來檢驗一下你理解的怎麼樣:

  1. person1.__proto__ 是什麼?
  2. Person.__proto__ 是什麼?
  3. Person.prototype.__proto__ 是什麼?
  4. Object.__proto__ 是什麼?
  5. Object.prototype__proto__ 是什麼?

答案:
第一題:
因為 person1.__proto__ === person1 的建構函式.prototype
因為 person1的建構函式 === Person
所以 person1.__proto__ === Person.prototype

第二題:
因為 Person.__proto__ === Person的建構函式.prototype
因為 Person的建構函式 === Function
所以 Person.__proto__ === Function.prototype

第三題:
Person.prototype 是一個普通物件,我們無需關注它有哪些屬性,只要記住它是一個普通物件。
因為一個普通物件的建構函式 === Object
所以 Person.prototype.__proto__ === Object.prototype

第四題,參照第二題,因為 Person 和 Object 一樣都是建構函式

第五題:
Object.prototype 物件也有proto屬性,但它比較特殊,為 null 。因為 null 處於原型鏈的頂端,這個只能記住。
Object.prototype.__proto__ === null

好了,如果以上你都能明白,那就可以繼續深入學習第三篇教程了:


作者:Yi罐可樂
連結:https://www.jianshu.com/p/652991a67186
 

關於Fundebug

Fundebug專注於JavaScript、微信小程式、微信小遊戲、支付寶小程式、React Native、Node.js和Java實時BUG監控。 自從2016年雙十一正式上線,Fundebug累計處理了9億+錯誤事件,得到了Google、360、金山軟體、百姓網等眾多知名使用者的認可。歡迎免費試用!