js建立的每一個函數都有一個prototype屬性,這個屬性指向一個對象。這個對象用來存儲經過這個函數所建立的全部實例共有的屬性和方法, 這個對象稱爲全部實例的原型對象。每一個原型對象都包含一個constructor屬性,它指向prototype屬性所在的函數。編程
每當代碼讀取某個對象的某個屬性時,都會執行一次搜索,目標是具備給定名字的屬性。搜索首先從對象實例自己開始。若是在實例中找到了具備給定名字的屬性,則返回該屬性的值;若是沒有找到,則繼續搜索_proto_指針指向的原型對象,在原型對象中查找具備給定名字的屬性。若是在原型對象中找到了這個屬性,則返回該屬性的值。函數
經過實例只能訪問原型對象的值,不能修改原型對象的值。若是咱們在實例中添加了一個屬性,而該屬性與實例原型中的一個屬性同名,那麼就會在實例中建立該屬性,該屬性將屏蔽掉原型中的那個屬性。this
繼承是面向對象編程中的一個重要概念,經過繼承可使子類的實例使用在父類中定義的屬性和方法。spa
在js中咱們能夠建立一個對象o,經過這個對象能夠訪問父類中定義的全部屬性和方法,而後把這個對象做爲子類實例的原型對象。 這樣的話子類實例就能夠經過搜索原型來訪問父類中的全部屬性和方法。通常狀況下能夠經過建立父類對象的實例來建立對象o;舉例以下:prototype
1 function Animal(){ 2 3 } 4 Animal.prototype.shout=function(word){ 5 console.log(word); 6 } 7 8 function Bird(){ 9 10 } 11 Bird.prototype=new Animal(); 12 //爲原型添加constructor屬性; 13 Bird.prototype.constructor=Bird; 14 15 var bird=new Bird(); 16 bird.shout("gugugu...");
上例中shout屬性的查找過程:先查找bird實例,沒找的,再查找bird的原型對象,即Animal的實例,沒找到,接下來查找Animal實例的原型,找到。因爲每個實例都有一個原型,經過這種方式就會造成一條原型鏈,圖示以下:指針
1 function extend(subclass, superclass) { 2 "use strict"; 3 //建立一個對象做爲子類的原型對象 4 function o() { this.constructor = subclass; } 5 //設置對象的原型爲父類的原型,從而使對象能夠訪問父類方法 6 o.prototype = superclass.prototype; 7 return (subclass.prototype = new o()); 8 };