這兩天看這個理論知識畜伐,看的有點小惡心了√陕剩÷杲纾現(xiàn)在稍微總結(jié)一下,大體知道的悼吱,然后不全的再隨著自己的理解往上加慎框。
函數(shù)表達式
-
什么是函數(shù)表達式?
定義函數(shù)有兩種方式后添,一個是函數(shù)聲明笨枯,另一個是函數(shù)表達式。函數(shù)聲明最重要的一個特征是函數(shù)聲明提升。
函數(shù)聲明:function functionName(arg0猎醇, arg1窥突, arg2){ //函數(shù)體 }
函數(shù)表達式:
var functionName = function(arg0, arg1, arg2) {
//函數(shù)體
}
-
為啥會出現(xiàn)函數(shù)表達式?
既然函數(shù)聲明比較好理解硫嘶,同時還具有函數(shù)聲明提升的特征阻问,為啥要出現(xiàn)函數(shù)表達式?沦疾?
原因一:if(condition) { function sayHi( ){ alert(" Hi ! "); } }else{ function sayHi( ){ alert(" Yo ! "); } }
其實上面代碼的本意是很清楚的称近,希望能根據(jù)不同的condition可以執(zhí)行不同的部分。但是哮塞,函數(shù)聲明提升會導致語法錯誤刨秆,而各個瀏覽器修復錯誤的方式是不同的,所以執(zhí)行結(jié)果也會不同忆畅。這個時候衡未,函數(shù)表達式可以解決這個問題。
if(condition) {
sayHi = function ( ){
alert(" Hi ! ");
}
}else{
sayHi function ( ){
alert(" Yo ! ");
}
}
原因二:
javascript中沒有塊級作用域的概念家凯,可以使用函數(shù)表達式缓醋、匿名函數(shù)來模擬實現(xiàn)這個功能。
var someFunction = function( ) {
//這里是塊級作用域
}绊诲;
someFunction( );
同時在這里說一下“立即執(zhí)行函數(shù)表達式”送粱,常見的幾種方式包括
(1)
( function ( ){
console.log(" test ! ");
})( );
(2)
( function ( ){
console.log(" test ! ");
}( ));
以上是正確的“立即執(zhí)行函數(shù)表達式”的正確寫法〉嘀可能很多人會有疑問抗俄,為什么要這樣子寫?世舰?
function ( ){ }( ); //出錯
當像上面這樣寫的時候动雹,會出現(xiàn)語法錯誤,因為javascript當遇到function關(guān)鍵字時跟压,會當作函數(shù)聲明的開始洽胶,而函數(shù)聲明后面跟的應該是函數(shù)名,而不能是圓括號裆馒,所以會出現(xiàn)語法錯誤姊氓。那為啥上面兩種方法就可以實現(xiàn)“立即執(zhí)行”的功能,不報錯呢喷好。因為javascipt中語法中翔横,()里面會自動解析成表達式,而不是語句梗搅。比如:
/ / 如果傳入字面量(literal)禾唁,則返回表達式(expression)
(1) // 1
(function(){console.log("f");}) // function () {console.log("f")}
通過上面的描述應該大概懂了一些效览,那如何實現(xiàn)模擬塊級作用域的呢。
//a.js
var num = 1;
// code....
//b.js
var num = 2;
// code....
當同時引入a.js荡短、b.js時丐枉,一定會造成num變量的覆蓋,為了解決這個問題掘托,我們的“立即執(zhí)行函數(shù)表達式”就發(fā)揮作用了呢瘦锹。
a.js
(function(){
var num = 1;
// code....
})();
b.js
(function(){
var num = 1;
// code....
})();
經(jīng)過改造之后,現(xiàn)在兩個庫成為完全獨立的了闪盔,就可以放心大膽的使用了弯院。
匿名函數(shù):顧名思義,就是沒有名字的函數(shù)泪掀。
匿名函數(shù)的用途之一就是把函數(shù)當成值來使用听绳。
閉包
啥是閉包?
閉包就是能夠讀取其它函數(shù)內(nèi)部變量的函數(shù)异赫。是將函數(shù)內(nèi)部和函數(shù)外部連接起來的一座橋梁椅挣。閉包的用處?塔拳?
為啥會出現(xiàn)閉包呢鼠证,因為javascript作用域鏈的作用,函數(shù)內(nèi)部可以訪問函數(shù)外部的作用域蝙斜,但是外部想訪問內(nèi)部的變量就不可以了。閉包的最大用處有2個澎胡,一個是可以讀取函數(shù)內(nèi)部的變量孕荠,另一個就是可以讓這些變量的值始終保持在內(nèi)存中。-
閉包經(jīng)常出現(xiàn)的問題
function createFunctions(){ var result = new Array(); for(var i = 0; i < 10; i++){ result[i] = function(){ return i; }; } return result; }
上面代碼返回的數(shù)組攻谁,每個函數(shù)都返回的是10稚伍。因為每個函數(shù)的作用域鏈中都保存著createFunctions()函數(shù)的活動對象,所以它們引用都是同一個變量i戚宦。我們可以通過創(chuàng)建另一個匿名函數(shù)強制讓閉包的行為符合預期个曙。
function createFunctions(){
var result = new Array();
for(var i = 0; i < 10; i++){
result[i] = function(num){
return function(){
return num;
};
}(i);
}
return result;
}
-
閉包用來模擬單例
var counter = (function(){ var i = 0; return { get: function(){ return i; }, set: function( val ){ i = val; }, increment: function() { return ++i; } }; }()); counter.get(); // 0 counter.set( 3 ); counter.increment(); // 4 counter.increment(); // 5