經過一個簡單的的例子,來展現如何使用JavaScript在類裏面建立私有變量和方法 javascript
另外注意下這種寫法: var 函數名=function 函數名(){...} 這個函數被調用時具備特權函數和私有函數的特性。 html
例: java
<html> <head> <title></title> <script type="text/javascript"> function Container( param ) { function dec(){ if ( secret > 0 ) { secret -= 1; setSecret( 7) alert( secret ); return true; } else { // alert( "over"+this.member); return false; } } // this.dec = dec; //this.dec = function dec (){...} different from above code. function setSecret( num ){ secret = num; } this.member = param; var secret = 3; var self = this; this.service = function () { if (dec()) { alert(); } else { return null; } } } // --------------------------------------- function start(){ alert( "Start" ) var test = new Container( 'liuqi' ); // test.setSecret( 2 ); test.service(); test.service(); test.service(); test.service(); var test2 = new Container( 'liuqi' ); //test2.service(); // Container.dec(); } </script> </head> <body> <div onclick="start()" style="color:blue">click me</div> </body> </html>
JavaScript是世界上最被誤解的編程語言。有人認爲它缺乏信息隱藏的特性,由於JavaScript對象不能擁有私有變量的方法。
可是這是個誤解。JavaScript對象能夠擁有私有成員。
對象
JavaScript從根本上就是關於對象的。數組是對象,方法是對象,Object也是對象。什麼是對象?對象就是鍵值對的集合。鍵是字符串,
值能夠是字符串,數字,布爾和對象(包括數組和方法)。對象一般被實現爲Hashtable,這樣值就能夠被快速獲取。
若是值是一個函數,我能夠稱其爲方法。當對象的方法被調用時,「this」變量則被賦予該對象。方法能夠經過「this」變量訪問實例
變量。
對象能夠由初始化對象的方法 -- 構造函數產生。構造函數提供在其餘編程語言中類提供的特性,包括靜態變量和方法。
Public
對象的成員都是public成員。任何對象均可以訪問,修改,刪除這些成員或添加新成員。主要有兩種方式來在一個新對象裏放置成員:
在構造函數裏
這種技術一般用來初始化public實例變量。構造函數的「this」變量用來給對象添加成員。 編程
functin Container(param) { this.member = param; } functin Container(param) { this.member = param; }
這樣,若是咱們構造一個新對象var myContainer = new Container('abc'),則myContainer.member爲'abc'。
在prototype裏
這種技術一般用來添加public方法。當尋找一個成員而且它不在對象自己裏時,則從對象的構造函數的prototype成員裏找。
prototype機制用來作繼承。爲了添加一個方法到構造函數建立的全部對象裏,只需添加到構造函數的prototype: 數組
Container.prototype.stamp = function (string) { return this.member + string; } Container.prototype.stamp = function (string) { return this.member + string; }
這樣,咱們能夠調用該方法myContainer.stamp('def'),結果爲'abcdef'。
Private
private成員由構造函數產生。普通的var變量和構造函數的參數都稱爲private成員。 閉包
Java代碼 編程語言
function Container(param) { this.member = param; var secret = 3; var that = this; } function Container(param) { this.member = param; var secret = 3; var that = this; }
該構造函數建立了3個private實例變量: param,secret和that。它們被添加到對象中,可是不能被外部訪問,也不能被該對象本身的
public方法訪問。它們只能由private方法訪問。private方法是構造函數的內部方法。 函數
function Container(param) { function dec() { if (secret > 0) { secret -= 1; return true; } else { return false; } } this.member = param; var secret = 3; var that = this; } function Container(param) { function dec() { if (secret > 0) { secret -= 1; return true; } else { return false; } } this.member = param; var secret = 3; var that = this; }
private方法dec檢查secret實例變量。若是它大於0,則減小secret並返回true,不然返回false。它能夠用來讓這個對象限制用3次。
按照慣例,咱們定義一個private的that變量。這用來讓private方法能夠使用本對象。這樣作是由於ECMAScript語言規範有一個錯誤,
該錯誤致使不能正確的設置this給內部方法。
private方法不能被public方法調用。爲了讓private方法有用,咱們須要引入privileged方法。
Privileged
privileged方法能夠訪問private變量和方法,而且它自己能夠被public方法和外界訪問。能夠刪除或替代privileged方法,可是不能
更改它或強制它泄露本身的祕密。
privileged方法在構造函數裏用this分配。 this
Java代碼 spa
function Container(param) { function dec() { if (secret > 0) { secret -= 1; return true; } else { return false; } } this.member = param; var secret = 3; var that = this; this.service = function() { if (dec()) { return that.member; } else { return null; } }; } function Container(param) { function dec() { if (secret > 0) { secret -= 1; return true; } else { return false; } } this.member = param; var secret = 3; var that = this; this.service = function() { if (dec()) { return that.member; } else { return null; } }; }
service是privileged方法。前三次調用myContainer.service()將返回'abc'。以後,它將返回null。service調用private的dec方法,
dec方法訪問private的secret變量。service對其餘對象和方法可見,可是它不容許直接訪問private變量。
閉包
因爲JavaScript有閉包,public,private和privileged成員的模式是可行的。這意味着一個內部方法始終能夠訪問它的外部方法的
var變量和參數,甚至在外部方法返回以後。這是JavaScript語言的一個很是強大的特性。當前沒有展現如何發掘這種特性的JavaScript
編程書籍,大多數甚至都沒提到。
private和privileged成員只能在對象被構造時產生。public成員則能夠在任什麼時候候添加。
模式
public
Java代碼
function Constructor(...) { this.membername = value; } Constructor.prototype.membername = value; function Constructor(...) { this.membername = value; } Constructor.prototype.membername = value;
Private
Java代碼
function Constructor(...) { var that = this; var membername = value; function membername(...) {...} } // 注意: function語句 // function membername(...) {...} // 是以下代碼的簡寫 // var membername = function membername(...) {...}; function Constructor(...) { var that = this; var membername = value; function membername(...) {...} } // 注意: function語句 // function membername(...) {...} // 是以下代碼的簡寫 // var membername = function membername(...) {...};
Privileged
Java代碼
function Constructor(...) { this.membername = function (...) {...}; } function Constructor(...) { this.membername = function (...) {...}; }
譯者注:我認爲能夠簡單的把privileged方法簡單的當作是構造函數裏的public方法,由於privileged方法能夠被外界和public方法訪問,
而它自身又能夠訪問private變量。