四. __proto__
JS 在創建對象(不論是普通對象還是函數對象)的時候,都有一個叫做__proto__
的內置屬性,用于指向創建它的構造函數的原型對象。
對象 person1 有一個 __proto__
屬性,創建它的構造函數是 Person,構造函數的原型對象是 Person.prototype ,所以:
person1.__proto__ == Person.prototype
請看下圖:
根據上面這個連接圖,我們能得到:
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;
這些構造器都是函數對象:
六. 原型鏈
小測試來檢驗一下你理解的怎么樣:
-
person1.__proto__
是什么? -
Person.__proto__
是什么? -
Person.prototype.__proto__
是什么? -
Object.__proto__
是什么? -
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
好了,如果以上你都能明白,那就可以繼續深入學習第三篇教程了:
第三篇,點擊進入