原型本質(zhì):所有的構(gòu)造函數(shù)都有一個(gè)prototype屬性,該屬性是指向函數(shù)的原型對(duì)象
所有的實(shí)例都有一個(gè)_proto_屬性,該屬性指向產(chǎn)生實(shí)例對(duì)象的構(gòu)造函數(shù)的原型
_proto_不是標(biāo)準(zhǔn)屬性,在Chrome,Safari,Firefox瀏覽器叫_proto_,在別的瀏覽器這個(gè)屬性對(duì)腳本是不可見的, 實(shí)際上該屬性是瀏覽器內(nèi)部使用的,編程的時(shí)候不允許使用
_proto_屬性和構(gòu)造函數(shù)中的prototype指向同一塊區(qū)域.因此下面代碼結(jié)果為true
console.log(Person.prototype===p1.__proto__) //true
原型的好處就是可以實(shí)現(xiàn)實(shí)例對(duì)象之間共享屬性和方法
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.showName =function(){console.log(this.name);}
Person.prototype.showAge =function(){console.log(this.age);}
Person.prototype.arr = ['red','yellow'];
var p1 = new Person('zhangsan',12);
var p2 = new Person('lisi',13);
p1.showName();
p2.showName();
console.log(p1.showName === p2.showName);//true
我們?cè)谡{(diào)用p1.showName()與p2.showName()時(shí),解析器會(huì)問(wèn):實(shí)例p1中有showName屬性嗎?答案是:沒(méi)有? 然后繼續(xù)問(wèn):p1原型中有showName屬性嗎?答案是:有,因此就可以讀取到在原型中的showName函數(shù)
上邊代碼 給原型中的arr數(shù)組push新的值,如p1.arr.push('black');p1與p2訪問(wèn)到的值也是相同的
注意
如果寫成p1.arr = ['pink'];相當(dāng)于創(chuàng)建了一個(gè)新的屬性,加到p1的實(shí)例對(duì)象,并沒(méi)有加到原型中;
因此獲取p1.arr的值就是pink,在執(zhí)行p1.arr的時(shí)候
解析器會(huì)問(wèn):實(shí)例對(duì)象p1中有arr屬性嗎? 答案是:有 ,如果在實(shí)例對(duì)象中找到了具有給定名字的屬性,那么就直接返回屬性的值,如果沒(méi)有找到才會(huì)到原型對(duì)象中找
總結(jié)
通過(guò)obj.arr =值;相當(dāng)于創(chuàng)建了一個(gè)新的屬性,加到obj中實(shí)例對(duì)象
但是obj.arr.push(123);這種結(jié)構(gòu)不會(huì)再obj中添加一個(gè)屬性,而是在arr中添加了一個(gè)值