天天看點

javascript 實作 私有、公有 方法

IE8正式版出來了,喜歡圖新鮮的我,便下載下傳了個來安裝。但随之,問題也來了,prototype.js架構出了問題,上網查了一下,就順便下載下傳了prototype對應于IE8的更新版本。打開看了一下代碼,發現其中發生了不少變化,但其中有一點讓我眼前一亮:javascript原來也可以實作私有方法了。先看一下我的代碼:

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<title>Javascript實作私有方法</title>

<mce:script language="javascript" type="text/javascript"><!--

//藍色_冰點 原創

//聲明一個類

function MyClass()

{

this.name="MyClass";

}

MyClass.prototype=(function(){

//私有成員,為了便于區分,我用 _ 作為私有方法的字首

function _ShowName()

{

alert(this.name);

}

function _setName(value)

{

this.name=value;

}

//公有成員

function ShowName()

{

_ShowName();

//this._ShowName();

//_ShowName.call(this);

}

function setName(value)

{

_setName(value);

//this._setName(value);

//_setName.call(this,value);

}

return {

//在這裡,将公有方法作為prototype對象傳回

ShowName:ShowName,

setName:setName

}

})();

var test1=new MyClass();

var test2=new MyClass();

test1.setName("test1");

test2.setName("test2");

test1.ShowName();

test2.ShowName();

//通路私有方法

try

{

test1._ShowName();

}

catch(err)

{

alert("試圖通路對象的私有方法:/r/n"+err.description);

}

// --></mce:script>

</head>

<body>

</body>

</html>

首先解釋一下,對于MyClass.prototype=(function(){... return {...}; })();這個奇怪的東西,因為初學者一定會被它弄得莫名奇妙,當初我第一次看到這種類似的代碼,也是不解。

函數的聲明方式通常是

function myFun()

{

    ....;

}

但我也們也可以省去函數名,這樣就成了

function()

{

}

問題馬上來了,這樣聲明後,怎麼調用它呢?沒有名字啊。。。。。其實有些地方,我們隻需要用一次某個方法的時候,我們就可以這樣聲明了,比如這樣:

window.οnlοad=function()

{

    //頁面初始化代碼

}

那麼接着就是 (function(){})(); 這又是什麼意思呢?我們調用一個方法的時候就像這樣:

myFun();

是以我們可以這樣了解:  在函數名後面加上(),就可以調用它,是以我們聲明了一個沒有名字的函數function(){} 後,馬上調用它,是以就成了 function(){}(); 這個樣子了,當然再加上個()調整一下優先級(其實也可以不用加),就成了這樣 (function(){})();這種奇怪形式了。至于return {}; 這是json格式,在此不介紹,自己百度一下吧。

OK,既然都明白了,那麼運作一下吧。看看結果。

結果?等等,為什麼結果是兩個test2?這跟我們想要的不一樣啊。。。

其實在我的代碼中ShowName和setName各留了兩行被注釋掉的代碼

如果在ShowName中直接調用私有方法_ShowName的話,ShowName被應用于執行個體test1和test2上,但_ShowName卻沒有,是以在_ShowName中的this.name并沒有通路到MyClass中的this.name,而此時_ShowName中的this代表window。是以通路失敗,正确的調用應該是_ShowName.call(this); 當然this._ShowName();也是不行的,因為_ShowName并沒有被作為prototype的一個成員傳回給MyClass。是以其實MyClass并沒有_ShowName這個方法。

方法是有些麻煩,但也算是實作了

繼續閱讀