我們建立的每個函式都有一個prototype(原型)屬性,這個屬性是一個指標,一個物件。無論什麼時候,我們只要建立一個新函式,就會根據一組特定的規則為該函式建立一個prototype屬性,這個屬性物件指向函式的原型物件。在預設情況下,所有原型物件都會自動獲得一個 constroctor(建構函式)屬性,這個屬性包含一個指向prototype屬性所在函式的指標。例如:

function Person(){}

當我們建立這個Person函式(物件)的時候,該函式便有了一個prototype屬性,它的原型物件Person.prototype會獲得一個constroctor屬性,那麼Person.prototype.constroctor便指向了Person。更直白一點講就是,如果我們再此基礎上再加一句

var p=new Preson();

  那麼,p的原型就會指向構造器的prototype屬性,也就是Person.prototype。

那麼,原型鏈具體的工作機制是什麼?請看下面這個例子

function foo(){}
foo.prototype.z=3; var obj=new foo();
obj.y=2;
obj.x=1; obj.x;//
obj.y;//
obj.z;// typeof obj.toString();//'function'
'z' in obj;//true
obj.hasOwnProperty('z');//false

當輸出obj.z的時候,並不會因為obj物件沒有z屬性而輸出undefied,而是查詢obj的原型也就是foo.prototype,這是js發現z的值是3,所以就會輸出obj.z的值為3.

實際上,我們用物件字面量建立的函式物件,其原型obj.prototype會指向Object.prototype,而Object.prototype也是由原型的,其值是null,這是上就是一個

原型鏈,而這也是  typeof obj.toString(); 為function的原因,因為沿著原型鏈向上查詢,便找到了object中的toString方法。