JavaScript的public、private和privileged模式

公共/私有變量和方法

經過一個簡單的的例子,來展現如何使用JavaScript在類裏面建立私有變量和方法 javascript


Summary
  • 私有變量 在對象內部使用'var'關鍵字來聲明,並且它只能被私有函數和特權方法訪問。
  • 私有函數 在對象的構造函數裏聲明(或者是經過var functionName=function(){...}來定義),它能被特權函數調用(包括對象的構造函數)和私有函數調用。
  • 特權方法 經過this.methodName=function(){...}來聲明並且可能被對象外部的代碼調用。它能夠使用:this.特權函數() 方式來調用特權函數,使用 :私有函數()方式來調用私有函數。
  • 公共屬性 經過this.variableName來定義並且在對象外部是能夠讀寫的。不能被私有函數所調用。
  • 公共方法 經過ClassName.prototype.methodName=function(){...}來定義並且能夠從對象外部來調用。
  • 原型屬性 經過ClassName.prototype.propertyName=someValue來定義。
  • 靜態屬性 經過ClassName.propertyName=someValue來定義。

另外注意下這種寫法: var 函數名=function 函數名(){...} 這個函數被調用時具備特權函數和私有函數的特性。 html


例: java



Js代碼
  1. <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;

}


該構造函數建立了3private實例變量: paramsecretthat。它們被添加到對象中,可是不能被外部訪問,也不能被該對象本身的
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次。
按照慣例,咱們定義一個privatethat變量。這用來讓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'。以後,它將返回nullservice調用privatedec方法,
dec
方法訪問privatesecret變量。service對其餘對象和方法可見,可是它不容許直接訪問private變量。

閉包
因爲JavaScript有閉包,publicprivateprivileged成員的模式是可行的。這意味着一個內部方法始終能夠訪問它的外部方法的
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變量。

相關文章
相關標籤/搜索