原文鏈接:https://my.oschina.net/u/2331760/blog/468672?p={{currentPage+1}}
函數基本概念:
函數聲明:function box(){}
函數表達式:var box = function(){};
匿名函數:function(){} 屬於函數表達式
匿名函數的作用:如果將匿名函數賦值給一個變量,則聲明了一個函數: var box= function(){};
如果將匿名函數賦予一個事件則成為事件處理程序: box.addEventListener("click",function(){alert("aaa")});
創建閉包:(function(){})()
函數定義的三種方法:
var box = function(){};
function box(){}
var box = new Function();
函數聲明和函數表達式的不同:
js在進行預解析時函數聲明會提升,而函數表達式必須js順序執行到此函數代碼時才會逐行解析
函數表達式后面加括號可以立即執行函數,函數聲明不可以,只能以fnName()的方式調用才行
實例:
box(); function box(){ alert("aaa"); }
//正常,因為js在解析階段函數聲明會被提升到最前面,所以函數聲明可以在函數執行后面
//實際順序
//function box(){
alert("aaa");
}
//box();
box();
var box = function(){
alert("aaa");
}
//報錯,實際上的順序是
//var box = undefined;
//box();
//box = function(){
alert("aaa");
}
//所以當執行到box()時,此時box不是一個函數
var box = function(){
alert("aaa");
}()
//正確 函數表達式后面加括號,當執行到后面的括號時js會自動執行此函數
function box(){
alert("aaa");
}()
//不會報錯,但是只會解析函數聲明,忽略后面的括號,不會自執行
function(){
alert("aaa")
}()
//語法錯誤
//雖然匿名函數屬於函數表達式,但未進行賦值給一個變量
//當js解析到function時,將其看成函數聲明,報錯,需要一個函數函數名
函數自執行
(function(a){ alert(a); })("123") //"123" 使用()運算符 (function(a){ alert(a); }("123")) //"123" 使用()運算符 !function(a){ alert(a); }("123") //"123" 使用!運算符
+function(a){
alert(a);
}("123")
//"123" 使用+運算符
-function (a){
alert(a);
}("123")
//"123" 使用-運算符
var fn= function(a){
alert(a);
}("123")
//"123" 使用=運算符
在function前面加!、+、-、=都可以將函數聲明轉化為函數表達式,消除了js引擎識別函數聲明和函數表達式的歧義,
加()是最安全的方法,免得其他的和函數返回值進行運算
不過這樣的寫法有什么用呢?
javascript中沒用私有作用域的概念,如果在多人開發的項目上,你在全局或局部作用域中聲明了一些變量,可能會被其他人不小心用同名的變量給覆蓋掉,
根據javascript函數作用域鏈的特性,可以使用這種技術可以模仿一個私有作用域,用匿名函數作為一個“容器”,
“容器”內部可以訪問外部的變量,而外部環境不能訪問“容器”內部的變量,
所以( function(){…} )()內部定義的變量不會和外部的變量發生沖突,俗稱“匿名包裹器”或“命名空間”。
JQuery使用的就是這種方法,將JQuery代碼包裹在( function (window,undefined){…jquery代碼…} (window)中,在全局作用域中調用JQuery代碼時,可以達到保護JQuery內部變量的作用。