深入了解javascript原型和原型鏈
一、什么是原型
原型:每一個(gè)javascript對(duì)象(除null外)創(chuàng)建的時(shí)候,都會(huì)與之關(guān)聯(lián)另一個(gè)對(duì)象,這個(gè)對(duì)象就是我們所說(shuō)的原型,每一個(gè)對(duì)象都會(huì)從原型中“繼承”屬性。
例如
var obj = new Object();
創(chuàng)建一個(gè)對(duì)象的時(shí)候都會(huì)同時(shí)關(guān)聯(lián)一個(gè)對(duì)象,如圖,關(guān)聯(lián)的這個(gè)對(duì)象就是新建的對(duì)象obj的原型
二、prototype
在JavaScript中,每個(gè)函數(shù)都有一個(gè)prototype屬性,這個(gè)屬性指向函數(shù)的原型對(duì)象。(ps:函數(shù)其實(shí)也是一個(gè)對(duì)象,所以與上述一、中的例子不沖突)
var obj = new Object();
所謂的prototype其實(shí)就是對(duì)象與對(duì)象的原型關(guān)聯(lián)的屬性,如圖
例如:
function Animal(weight) { this.weight = weight }
如圖表示對(duì)象與原型的關(guān)聯(lián):
每一個(gè)對(duì)象都會(huì)從原型中“繼承”屬性
例如:cat1和cagt2實(shí)例化了Animal,在cat1和cagt2本身是沒(méi)有hieght屬性的,但是能打印出height的值均為10,其實(shí)是在cat1和cagt2繼承了原型Animal.prototype中的height屬性
function Animal(weight) { this.weight = weight } Animal.prototype.height = 10 var cat1 = new Animal() var cat2 = new Animal() console.log('cat1',cat1.height)//10 console.log('cat2',cat2.height)//10
三、__proto__
這是每個(gè)對(duì)象(除null外)都會(huì)有的屬性,叫做__proto__,這個(gè)屬性會(huì)指向該對(duì)象的原型。
function Animal(weight) { this.weight = weight } Animal.prototype.height = 10 var cat1 = new Animal() var cat2 = new Animal() console.log('cat1.__proto__ === Animal.prototype',cat1.__proto__ === Animal.prototype) console.log('cat2.__proto__ === Animal.prototype',cat2.__proto__ === Animal.prototype)
__proto__和prototype
- __proto__是實(shí)例指向原型的屬性
- prototype是對(duì)象或者構(gòu)造函數(shù)指向原型的屬性
四、constructor
每個(gè)原型都有一個(gè)constructor屬性,指向該關(guān)聯(lián)的構(gòu)造函數(shù)。
function Animal(weight) { this.weight = weight } Animal.prototype.height = 10 var cat1 = new Animal() var cat2 = new Animal() console.log('cat1.__proto__ === Animal.prototype',cat1.__proto__ === Animal.prototype) console.log('Animal===Animal.prototype.constructor',Animal===Animal.prototype.constructor) // 獲取原型對(duì)象 console.log('Object.getPrototypeOf(cat1) === Animal.prototype',Object.getPrototypeOf(cat1) === Animal.prototype)
更新關(guān)系圖
cat1.__proto__?===?Animal.prototype
Animal?===?Animal.prototype.constructor
那么cat1.constructor?===?Animal為true 嗎?答案是true,因?yàn)槊恳粋€(gè)對(duì)象都會(huì)從原型中“繼承”屬性,cat1中并沒(méi)有屬性constructor ,但是它的原型cat1.__proto__ 指向的是Animal.prototype,然而Animal.prototype原型中是有屬性constructor的,于是cat1的constructor屬性繼承與原型中的constructor屬性。這里便能看出一點(diǎn)點(diǎn)原型鏈的影子了,我們接著看
因此cat1.constructor?===?Animal 也是 true
五、實(shí)例與原型
?當(dāng)讀取實(shí)例的屬性時(shí),如果找不到,就會(huì)查找與對(duì)象關(guān)聯(lián)的原型中的屬性,如果還查不到,就去找原型的原型,一直找到最頂層為止。這樣就形成了原型鏈
function Animal(weight) { this.weight = weight } Animal.prototype.name = 'animal' var cat1 = new Animal() cat1.name = 'littleCat' console.log('cat1.name',cat1.name) delete cat1.name; console.log('cat1.name',cat1.name)
可以看見,刪除屬性前,那么是littleCat,刪除那么屬性后,該實(shí)例沒(méi)有了name屬性,找不到name屬性的時(shí)候,它就會(huì)去 它的對(duì)象原型中去找也就是去cat1.__proto__中也就是Animal.prototype中去尋找,而Animal.prototype中的name屬性的值是animal,所以刪除name屬性后的值變成了原型中屬性name的值animal
那么接著來(lái)看,如果cat1的原型中也沒(méi)有name屬性呢?會(huì)怎么辦?去原型的原型中找?那么原型的原型是什么?
六、原型的原型
我們說(shuō)原型是對(duì)象創(chuàng)建的時(shí)候關(guān)聯(lián)的另一個(gè)對(duì)象,那么原型也是一個(gè)對(duì)象,既然是對(duì)象那么原型也應(yīng)該關(guān)聯(lián)一個(gè)對(duì)象是原型的原型
那么原型對(duì)象創(chuàng)建的時(shí)候也會(huì)關(guān)聯(lián)一個(gè)對(duì)象
var obj = new Object();
看關(guān)系圖
那么Object.prototype的原型呢?
也就是 Object.prototype.__proto__是什么呢
console.log('Object.prototype.__proto__ === null',Object.prototype.__proto__ === null)
可以看到結(jié)果
也就說(shuō)Object.prototype.__proto__ 的值為 null 即?Object.prototype 沒(méi)有原型,所以可以想象在原型鏈中,當(dāng)屬性找到頂層原型都沒(méi)有屬性那就是沒(méi)有這個(gè)屬性
七、原型鏈
綜上所述 ,將原型的實(shí)例賦值給另一個(gè)對(duì)象,另一個(gè)對(duì)象再賦值給其他的對(duì)象,在實(shí)際的代碼中對(duì)對(duì)象不同的賦值,就會(huì)形成一條原型鏈。這樣說(shuō)可能很抽象,我們來(lái)看個(gè)例子
function Animal(weight) { this.weight = weight } Animal.prototype.name = 'animal' var cat1 = new Animal() var pinkCat = cat1 console.log('pinkCat.name',pinkCat.name) console.log('pinkCat.__proto__ === cat1.__proto__ == Animal.prototype',pinkCat.__proto__ === cat1.__proto__ == Animal.prototype) var samllPinkCat = pinkCat console.log('samllPinkCat.name',samllPinkCat.name) console.log(samllPinkCat.__proto__ == pinkCat.__proto__ === cat1.__proto__ == Animal.prototype)
以上就是原型鏈一層一層鏈接上去形成一條鏈條就是所謂的原型鏈;以上cat1實(shí)例化了Animal,cat1賦值給了pinkCat,pinkCat又賦值給了samllPinkCat,就形成看原型鏈,從samllPinkCat,pinkCat到cat1最后到Animal
以上所述是小編給大家介紹的深入了解javascript原型和原型鏈,希望對(duì)大家有所幫助。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
JavaScript 無(wú)符號(hào)右移運(yùn)算符
無(wú)符號(hào)右移運(yùn)算符 (>>>)是右移表達(dá)式的位,不保留符號(hào)。2009-04-04向JavaScript的數(shù)組中添加元素的方法小結(jié)
這篇文章主要介紹了向JavaScript的數(shù)組中添加元素的方法小結(jié),分別舉了一些JS數(shù)組操作的例子,基本需要的朋友可以參考下2015-10-10JavaScript中Math對(duì)象使用說(shuō)明
2008-01-01JavaScript replace(rgExp,fn)正則替換的用法
再看jQuery源碼的時(shí)候遇到了replace中參數(shù)為函數(shù)的用法,正好復(fù)習(xí)一下replace正則替換的用法。2010-03-03再JavaScript的jQuery庫(kù)中編寫動(dòng)畫效果的指南
這篇文章主要介紹了再JavaScript的jQuery庫(kù)中編寫動(dòng)畫效果的指南,包括一些內(nèi)建的效果方法的使用示例,需要的朋友可以參考下2015-08-08JavaScript instanceof 的使用方法示例介紹
判斷一個(gè)變量的類型嘗嘗會(huì)用 typeof 運(yùn)算符而他畢竟有些缺陷,就是無(wú)論引用的是什么類型的對(duì)象,它都返回object,這時(shí)就要用到instanceof來(lái)檢測(cè)某個(gè)對(duì)象是不是另一個(gè)對(duì)象的實(shí)例2013-10-10