封裝是面向對象的基礎,今天所要學習的匿名函數與閉包就是為了實現JS的面向對象封裝。封裝實現、封裝變量,提高數據、系統安全性,封裝正是面向對象的基礎。
## 一、匿名函數
即沒有名字的函數,其創建方式為
`function(){...}`
單獨存在的匿名函數,無法運行,可通過賦值給變量調用或通過表達式自我執行來實現運行。
1.賦值給變量為一般的函數使用方式
~~~
var run = function(){
return '方法運行中';
};
alert(run());
~~~
2.通過表達式自我執行
~~~
(function(arguments可選)
{
alert('方法運行中');
})(arguments);
~~~
## 二、閉包
在一個普通函數的內部,創建一個匿名函數,匿名函數可訪問普通函數中的變量,進而實現類似于面向對象中封裝的特性,這個匿名函數就叫做對應普通函數的閉包。閉包就是對外創建的接口,通過接口達到訪問函數內部變量的效果。
~~~
functionrun() {
var?username = 'Forrest';
return function () { //通過匿名函數返回 box()局部變量
return?username;
};
}
//alert(username); //錯誤username is not defined
alert(run()());
~~~
特點:閉包中使用的局部變量會駐留在內存中,避免了使用全局變量造成的命名沖突等情況的發生。值得注意的是閉包中使用this關鍵字,指向的是window對象。
## 三、封裝
為了更好的安全性、數據保護,則需要對數據進行私有化的封裝,而JS中沒有塊級作用域的概念(即出了{}的范圍,仍可以訪問聲明的變量),但有了前面的基礎,我們就可以達到像其他正規面向對象語言的封裝效果。
~~~
function user(){
(function(){
for(i = 0; i<5; i++){
alert(i);
}
})();
alert(i); //此處無法訪問變量i
}
//私有作用域代替全局變量
(function(){
var username= 'Forrest';
alert(username);
})(); //匿名函數執行完畢后,變量立即銷毀
//訪問私有變量
function User(){
var username= Forrest; //私有變量
function learn(){ //私有函數
return '學習中';
};
//對外提供接口,間接訪問內部成員
this.userlearn = function(){
return username + learn();
};
}
var user = new User()
alert(user.userlearn());
//實現get()、set()
function User(value){
var user = value;
this.getUser = function(){
return user;
}
this.setUser = function(value){
user = value;
}
}
var user = new User('Forrest');
alert(user.getUser());
user.setUser('Li');
alert(user.getUser());
//靜態私有變量
(function(){
var user = '';
User = function(value){
user = value;
};
User.prototype.getUser = function(){
return user;
};
User.prototype.setUser = function(value){
user = value;
};
})();
//字面量方式的私有化
function NormalUser(){}
var user = function(){
var user = 'Forrest';
function learn(){
return user + '學習中...';
};
var nu = new NormalUser();
nu.userlearn = function(){
return learn();
};
return nu;
}();
alert(user.userlearn());
~~~
## 結語:
JS雖不是一門正統的面向對象的語言,但用它也能達到面向對象的封裝、繼承、多態等的效果,學習起來還是需要好好理解的,特別是對于使用JS不是特別多的人來說,只能等到以后的逐步應用來解決這一系列的問題,更進一步體會它在面向對象方面的應用。