|
私有變量 在對象內部使用'var'關鍵字來聲明,而且它只能被私有函數和特權方法訪問。
私有函數 在對象的構造函數里聲明(或者是通過var functionName=function(){...}來定義),它能被特權函數調用(包括對象的構造函數)和私有函數調用。
特權方法 通過this.methodName=function(){...}來聲明而且可能被對象外部的代碼調用。它可以使用:this.特權函數() 方式來調用特權函數,使用 :私有函數()方式來調用私有函數。
公共屬性 通過this.variableName來定義而且在對象外部是可以讀寫的。不能被私有函數所調用。
公共方法 通過ClassName.prototype.methodName=function(){...}來定義而且可以從對象外部來調用。
原型屬性 通過ClassName.prototype.propertyName=someValue來定義。
靜態屬性 通過ClassName.propertyName=someValue來定義。
另外注意下這種寫法: var 函數名=function 函數名(){...} 這個函數被調用時具有特權函數和私有函數的特性。
例:
復制代碼 代碼如下:
<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”變量用來給對象添加成員。
Java代碼
復制代碼 代碼如下:
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:
Java代碼
復制代碼 代碼如下:
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方法是構造函數的內部方法。
Java代碼
復制代碼 代碼如下:
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分配。
Java代碼
復制代碼 代碼如下:
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變量。
JavaScript技術:JavaScript的public、private和privileged模式,轉載需保留來源!
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。