原型及原型鏈?zhǔn)鞘裁?/h5>
JS中的對象纠屋,在創(chuàng)建時都會有一個內(nèi)置屬性据忘,即__proto__
屬性岖圈,該屬性指向一個對象讹语,事實上可以理解為對另一個對象的引用。而被引用的對象就是原型對象蜂科。與之相對的顽决,所有函數(shù)也可通過一個內(nèi)置屬性prototype
指向原型對象。
var a = new Object()
a.__proto__ === Object.prototype // true
var b = {}
b.__proto__ === Object.prototype // true
當(dāng)對象是由構(gòu)造器函數(shù)生成的時候导匣,結(jié)果也是一樣才菠。
function F() {}
var c = new F()
c.__proto__ === F.prototype // true
c.__proto__.__proto__ === Object.prototype // true
在上面的例子中,c.__proto__.__proto__
即構(gòu)成了一個連接到頂層Object.prototype
原型對象的鏈接贡定,這就是原型鏈赋访。通過以上例子,可以簡單的得到
對象.__proto__ === 對象的構(gòu)造函數(shù).prototype
Function.__proto__ === Function.prototype // true 函數(shù)也是一種對象
Function.__proto__.__proto__ === Object.prototype // true
事實上缓待,__proto__
和prototype
只是對象和函數(shù)中的兩個屬性名罷了蚓耽,它們分別指向一個原型對象,頂層的原型對象就是Object.prototype
所指向的對象旋炒。因為Object.prototype
指向的是一個對象步悠,那么該對象也有一個__proto__
屬性,又因為Object.prototype
是指向頂層原型對象国葬,那么
Object.prototype.__proto__ === null // true
原型的作用
說了這么多贤徒,接著說原型的作用芹壕。原型存儲著一些共有的屬性及方法汇四。所有對象(函數(shù)也是種對象)都可通過原型鏈來訪問其中的屬性。另外踢涌,既然__proto__
和prototype
只是代表引用通孽,那么就可以改變它們引用的原型對象。
如果改變原型對象屬性睁壁,會影響到與之關(guān)聯(lián)的其他對象對其屬性的調(diào)用背苦,畢竟對于對象都是引用而非拷貝,這需要特別注意潘明。
var x1 = {a:2};
var x2 = Object.create(x1);
x2.a; // 2
在上面的代碼中行剂,將x1
設(shè)置為x2
的原型,x2
此時就能訪問x1
對象的屬性钳降。
所以只要理解了在對象及函數(shù)背后含有指向另一個對象的屬性就好理解原型及原型鏈了厚宰。原型是為了方便存放一些公用屬性及方法,原型鏈就是用來指向原型的就好了。
另外铲觉,如果原型鏈中存在相同的屬性名時澈蝙,先鏈接到的屬性會屏蔽后面的相同屬性。
var x1 = {a:1};
x1.__proto__.a = 2;
x1.a // 1
delete x1.a // true
x1.a // 2
從上面的例子中可以看到撵幽,在對象內(nèi)部及對象原型設(shè)置擁有相同屬性名的a
灯荧,此時調(diào)用x1.a
得到的是1
,當(dāng)刪除自身屬性a
后盐杂,原型中的a
就會浮現(xiàn)出來逗载。
可以通過Object.getPrototypeOf(obj)
來獲取對象的原型。