ecma太拙嘴饒舌,本文力圖用簡單的測試樣本來說明問題
任意建立一個函數,其原型prototype立刻被自動建立:
Js代碼
- function Coo(){};
- alert(Coo.prototype.constructor); //=>function Coo(){}
執行個體化Coo的原型prototype被置於範圍scope的最頂端: Js代碼
- function Coo(){
- alert(Coo.prototype.constructor);
- }
- var c1 = new Coo(); // => function Coo(){ ..}
在執行個體化Coo之前修改其原型prototype,其範圍scope頂端自動調整為修改後的原型prototype,並且執行個體c1可沿原型鏈找到method方法 Js代碼
- function Coo(){
- alert(Coo.prototype.method); // => function(){} 範圍scope頂端自動調整為修改後的原型prototyp
- }
- Coo.prototype = { method : function(){} }
- var c1 = new Coo(); // => function(){}
- alert(c1.method); // => function(){}
在執行個體化過程內部重新設定Coo的屬性prototype: Js代碼
- function Coo(){
- alert(Coo.prototype.method); // => undefined 範圍scope頂端依舊為預設自動建立的原型prototype
- Coo.prototype = { method : function(){} }
- //注意:上面這行重新設定了Coo的[b]屬性[/b]prototype,
- //它已不再是Coo自動建立或是自動調整後的原型prototype了——這正是javascript原型機制的核心
- }
- var c1 = new Coo(); // => function(){}
- //所以,雖然貌似:
- alert(c1.prototype.method) // => function(){}
- //但此[b]屬性[/b]——"prototype"(),已非彼[b]原型[/b]——"prototype"了:
- alert(c1.method); // => undefined
所以在執行個體化過程內部,只能基於原型prototype來擴充或修改方法 Js代碼
- function Coo(){
- alert(Coo.prototype.method); // => undefined
- Coo.prototype.method = function(){}; // 在正宗原型prototype上擴充,非山寨!
- }
- var c1 = new Coo(); // => function(){}
- alert(c1.prototype.method); // => function(){}
- alert(c1.method); // => function(){};
盤根究底,既然在執行個體化過程內部重新設定Coo的屬性prototype,
那麼Coo的原型prototype又會去了哪兒呢? Js代碼
- function Coo(){
- Coo.prototype = { method : function(){ alert("執行個體化中");} };
- };
- Coo.prototype = { constructor : Coo, method : function(){} }
- var c1 = new Coo();
- alert(c1.prototype.method); // => function(){ alert("執行個體化中");} 糟糕!
- alert(c1.method); // => function(){} 謝天謝地!
- alert(c1.constructor === Coo ); // => true; 原型鏈都還在,但它們似乎只是在內部被儲存起來了
囉嗦了一大堆,簡而言之:
函數的原型prototype是在執行個體化(或執行函數自身)之前就被自動建立(可以被修改或重設引用)的。
而在執行個體化(或執行函數自身)過程中,重設的prototype已淪為一個普普通通的對象屬性了,
但是他卻並不會干擾正常的javascript執行個體方法的原型鏈尋找機制。
http://www.javaeye.com/topic/453432