當(dāng)創(chuàng)建了一個(gè)新函數(shù)位仁,就會(huì)為這個(gè)函數(shù)創(chuàng)建一個(gè)prototype屬性,這個(gè)屬性指向函數(shù)的原型對(duì)象方椎,原型對(duì)象會(huì)自動(dòng)獲得一個(gè)constructor屬性聂抢,這個(gè)屬性又指回函數(shù)。所以Person.prototype.constructor是指向Person的
原型對(duì)象默認(rèn)只會(huì)獲得constructor屬性棠众,其他屬性琳疏、方法是從Object繼承而來(lái)的。
當(dāng)new一個(gè)實(shí)例后闸拿,該實(shí)例內(nèi)部的屬性指針 ' [[Prototype]] ' 就會(huì)指向原型對(duì)象空盼,在所有實(shí)現(xiàn)中都無(wú)法訪(fǎng)問(wèn)到[[Prototype]],但可以通過(guò)Object.getPrototypeOf()返回它的值新荤,返回的對(duì)象就是這個(gè)對(duì)象的原型
當(dāng)我們?cè)L問(wèn)person1.sayName()時(shí)揽趾,會(huì)先搜索實(shí)例person1有saName屬性嗎?沒(méi)有就會(huì)繼續(xù)搜索苛骨,person1的原型有sayName屬性嗎篱瞎,有的話(huà)就會(huì)讀取保存在原型對(duì)象里的函數(shù)
雖然可以讀取保存在原型中的值,但是不能通過(guò)實(shí)例重寫(xiě)原型中的值痒芝,只會(huì)屏蔽俐筋,例如
function Person(){
}
Person.prototype.name = 'zzx';
Person.prototype.age = 22;
Person.prototype.job = 'Programmer';
Person.prototype.sayName = function(){
console.log(this.name);
}
var person1 = new Person();
var person2 = new Person();
person1.name = 'yzy';
console.log(person1.name); //'yzy'實(shí)例中的值
console.log(person2.name); //'zzx'原型中的值
即使將person1的name設(shè)置為null,也不會(huì)恢復(fù)指向原型的連接严衬,但是可以使用delete操作符完全刪除實(shí)例屬性澄者,從而重新訪(fǎng)問(wèn)原型中的屬性
使用hasOwnProperty()方法可以檢測(cè)一個(gè)屬性是存在于實(shí)例還是存在于原型中,這個(gè)方法只有給定屬性存在于對(duì)象實(shí)例中時(shí)才會(huì)返回true请琳。
function Person(){
}
Person.prototype.name = 'zzx';
Person.prototype.age = 22;
Person.prototype.job = 'Programmer';
Person.prototype.sayName = function(){
console.log(this.name);
}
var person1 = new Person();
console.log(person1.hasOwnProperty('name')); //false
person1.name = 'yzy';
console.log(person1.hasOwnProperty('name')); //true
delete person1.name;
console.log(person1.hasOwnProperty('name')); //false
當(dāng)設(shè)置person1.name=‘yzy'后:
有兩種方式使用in操作符:?jiǎn)为?dú)使用和在for-in循環(huán)中使用粱挡。單獨(dú)使用時(shí),in操作符會(huì)在通過(guò)對(duì)象訪(fǎng)問(wèn)給定屬性時(shí)返回true单起,無(wú)論該屬性會(huì)存在于實(shí)例還是原型中抱怔。因此配合Object.getOwnProperty()使用就知道該屬性是存在于對(duì)象中還是存在于原型中。
function hasPrototypeProperty(object, name){
return !object.hasOwnProperty(name) && (name in object);
}