標籤:作用 prototype 同名 get new alert function 建構函式 定義類
在Javascript--閉包一節中我們講解了閉包的範圍和範圍鏈的特性。瞭解到在外部一般是不可能訪問到內部範圍中的變數的,然而通過閉包我們可以定義特權方法訪問私人變數。下面先介紹塊級範圍再介紹幾種特權方法。
一、模仿塊級範圍
Javascript是沒有塊級範圍的概念的。所以我們在語句塊中定義的變數,其範圍是包含函數而非語句塊。
function outPut(count){ for(var j=0;j<count;j++){ alert(j); } alert(j); //計數 }
在Java、C++語句中,變數j在迴圈語句結束後就銷毀了。但再Javascript中,變數j則是函數outPut的變數。因此我們通過函數運算式的變式來模仿塊級範圍。
function outPut(count){ (function (){ for(var j=0;j<count;j++){ alert(j); } })(); alert(j); //error }
這個時候變數j只在私人範圍中有效,運行結束就銷毀。這種技術經常在全域範圍中被用在函數外部,從而限制向全域環境中添加過多變數、函數。
二、建構函式訪問法
現在我們介紹第一種訪問私人變數的方法--建構函式法。私人變數指在函數內部中定義的變數、參數及其它函數。
function Person(name){ var name=name; this.sayName=function(){ alert(name); } }; var person1=new Person("Bob"); var person2=new Person("Mike"); person1.sayName(); //Bob person2.sayName(); //Mike
sayName()方法就是Person所有執行個體的一個特權方法。但有個問題:
alert(person1.sayName==person2.sayName); //false
每個執行個體的同名特權方法都要重新建立。
三、借用原型訪問
function Person(name){ var name=name; Person.prototype.sayName=function(){ alert(name); } };
var person1=new Person("Bob"); person1.sayName(); //Bob var person2=new Person("Mike"); person1.sayName(); //Mike person2.sayName(); //Mike alert(person1.sayName==person2.sayName); //true
這種方法每個執行個體的特權方法都是動態共用的。但每個執行個體都沒有自己的私人變數。
四、組合訪問
function Person(name){ var name=name; Person.prototype.sayName=function(){ alert(name); }; this.sayPrivateName=function(){ alert(name); } };
將兩種方式融合,看看其訪問私人變數的效果:
var person1=new Person("Bob"); person1.sayName(); //Bob person1.sayPrivateName(); //Bob var person2=new Person("Mike"); person1.sayName(); //Mike person1.sayPrivateName(); //Bob person2.sayName(); //Mike alert(person1.sayName==person2.sayName); //true alert(person1.sayPrivateName==person2.sayPrivateName); //false
私人變數若痛過原型方法訪問,私人變數就是動態共用的;若通過執行個體方法訪問,私人變數在每個執行個體中都有其特異性。而執行個體屬性不同,執行個體屬性將覆蓋同名原型屬性,且永遠是特異性的。
五、模組模式
前面的方法都是為自訂類型建立特權方法,而模組模式是為單例建立特權方法。
var person=function(){ var name="Bob"; //私人變數 function privateFunction(){ //私人函數 alert(true); }; return { publicName:name, //特權屬性 publicMethod:function(){ //特權方法 return privateFunction(); } } }();
alert(person.publicName); //Bob person.publicMethod(); //true
簡言之,如果必須建立一個對象並對其進行初始化,且還要公開一些能夠訪問這些私人變數的方法,那麼就可以使用模組模式。
javascript--特權方法