本篇文章主要講JavaScript對象中的原型模式:chrome
不管何時,只要建立了一個新函數,就會根據一組特定的規則爲該函數建立一個prototype屬性,這個屬性指向函數的原型對象。在默認狀況下,全部原型對象都會自動得到一個constructor(構造函數)屬性,這個屬性包含一個指向prototype屬性所在函數的指針。
建立了自定義的構造函數以後,其原型對象默認只會取得constructor屬性,至於其餘方法,則都是從object繼承而來的。當調用構造函數建立一個新實例後,該實例的內部將包含一個指針(內部屬性),指向構造函數的源性對象。ECMA-262第5版中管這個指針叫[[prototype]]。雖然在腳本中沒有標準的方式訪問[[prototype]],但FireFox、Safari和chrome在每一個對象上都支持一個屬性:proto;而在其餘實現中,這個屬性對腳本則是徹底不可見的。不過,要明確的真正重要的一點就是,這個鏈接存在於實例與構造函數的原型對象之間,而不是存在於實例與構造函數之間。函數
以下一段代碼:this
function Person(){ } Person.prototype.name="Jessica"; Person.prototype.age=25; Person.prototype.job="Web software Engineer"; Person.prototype.sayName=function(){ alert(this.name); } var person1=new Person(); person1.sayName(); //"Jessiva" var person2=new Person(); person2.sayName(); //"Jessiva" alert(person1.sayName==person2.sayName); //true
下圖展現了這段代碼的各個對象之間關係:spa
雖然在全部的實現中都沒法訪問到[[prototype]],但能夠經過isPrototypeOf()方法來肯定對象之間是否存在這種關係。從本質上講,若是[[prototype]]指向調用isPrototypeOf()方法的對象(Person.prototype),那麼這個方法就返回true,以下所示:prototype
alert(Person.prototype.isPrototypeOf(person1)); //true alert(Person.prototype.isPrototypeOf(person2)); //true
在ECMAScript5增長了一個新方法,叫object.getPrototypeOf(),在全部支持的實現中,這個方法返回[[prototype]]的值。例如:指針
alert(Object.getPrototypeOf(person1)==Person.prototype); //true alert(Object.getPrototypeOf(person1).name); //"Jessica"
使用Object.getPrototypeOf()能夠方便的取得一個對象的原型,而這在利用原型實現繼承(稍後會有文章更新)的狀況下是很是重要的。code
雖然能夠經過對象實例訪問保存在原型中的值,但卻不恩可以經過對象實例重寫原型中的值,若是咱們再實例中添加了一個屬性,而該屬性與實例原型中的一個屬性同名,那咱們就在實例中建立該屬性,該屬性將會屏蔽原型中的那個屬性。來看下面的例子:對象
function Person(){ } Person.prototype.name="Jessica"; Person.prototype.age=25; Person.prototype.job="Web software Engineer"; Person.prototype.sayName=function(){ alert(this.name); } var person1=new Person(); var person2=new Person(); person1.name="Greg"; alert(person1.name); //"Greg"--來自實例 alert(person2.name); //"Jessica"--來自原型
使用delete操做符則能夠徹底刪除實例屬性,從而讓咱們可以從新訪問原型中的屬性。繼承
使用hasOwnProperty()方法則能夠檢測一個屬性是存在於實例中仍是存在於原型中。這個方法(繼承於Object)只在給定屬性存在於對象實例中,纔會返回true。圖片