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這個方法。
方法是有些麻煩,但也算是實作了