讀古今文學網 > 編寫高質量代碼:改善JavaScript程序的188個建議 > 建議81:原型域鏈不是作用域鏈 >

建議81:原型域鏈不是作用域鏈

prototype是一種模擬面向對象的機制,它通過原型實現類與實例之間的繼承關係並進行管理。以prototype機制模擬繼承機制是一種原型繼承,它也是JavaScript的核心功能之一。但是,prototype的真正價值在於它能夠以對像結構為載體,創建大量的實例,這些實例能夠在構造類下實現共享。也正因為如此,很多人利用prototype的這個特性模擬對象的繼承機制。

protoype原型域可以允許原型屬性引用任何類型的對象。因此,如果在protoype原型域中沒有找到指定的屬性,那麼JavaScript將會根據引用關係,繼續向外查找protoype原型域所指向對象的protoype原型域,直到對象的prototype域為它自己,或者出現循環為止。下面這個示例演示了對象屬性查找的prototype規律。


function a(x){//構造函數a

this.x=x;

}

a.prototype.x=0;

function b(x){//構造函數b

this.x=x;

}

b.prototype=new a(1);//原型對像為構造函數a的實例

function c(x){//構造函數c

this.x=x;

}

c.prototype=new b(2);//原型對像為構造函數b的實例

var d=new c(3);

alert(d.x);//3

delete d.x;

alert(d.x);//2

delete c.prototype.x;

alert(d.x);//1

delete b.prototype.x;

alert(d.x);//0

delete a.prototype.x;

alert(d.x);//undefined


原型鏈可以幫助我們更清楚地認識JavaScript面向對象的繼承關係。每個對象實例都可以訪問它的構造器的原型,把這種層層指向父原型的關係稱為原型鏈(prototype chain),如圖4.5所示。

圖 4.5 原型鏈檢索示意圖

在JavaScript中,一切都是對象,函數是第一型。Function和Object都是函數的實例。構造函數的父原型指向Function的原型,Function.prototype的父原型是Object的原型,Object的父原型也指向Function的原型,Object.prototype是所有父原型的頂層。


Function.prototype.a=function{//Function原型方法

alert("Function");

}

Object.prototype.a=function{//Object原型方法

alert("Object");

}

function f{//構造函數f

this.a="a";

}

f.prototype={//構造函數f的原型方法

w:function{

alert("w");

}

}

alert(f instanceof Function);//true,說明f是Function的實例

alert(f.prototype instanceof Object);//true,說明f的原型也是對像

alert(Function instanceof Object);//true,說明Function是Object的實例

alert(Function.prototype instanceof Object);//true,說明Function的原型是Object的實例

alert(Object instanceof Function);//true,說明Object是Function的實例

alert(Object.prototype instanceof Function);//false,說明Object.prototype是所有父原型的頂層


原型的引用關係也容易帶來副作用。改變某個原型上的引用類型的屬性值,將會影響該原型作用的所有實例對象。很多時候這種動態影響會給程序帶來安全隱患。


function a{//構造函數a

this.x=;

}

function b{//構造函數b

}

b.prototype=new a;//構造函數b的原型指向a的實例

var f1=new b;

var f2=new b;

f1.x.push(1);

alert(f2.x);//1,說明實例f2的x屬性值也受到影響


上面的示例演示了原型對於不同實例的影響。構造函數a中的x屬性值為數組,該數組是引用類型的數據,而構造函數b的原型引用a的實例,於是直接引用了數組的指針,從而導致了實例之間相互影響的這種現象。