湯姆大叔的博客,本人學習階段,寫不出經典的東西,只能抄襲,可是本人尊重原創,so..附原文連接 http://www.cnblogs.com/TomXu/archive/2011/12/29/2290308.htmlhtml
前言json
簡單的說,命名函數表達式只有一個用戶,那就是在debug(調試)或者profiler(分析器)分析的時候來描述函數得名稱,也可使用函數名實現遞歸,但很快你就會發現實際上是不切實際的,固然,若是你不關注調試,那就沒什麼可擔憂了,不然,若是你想了解兼容性方面的東西的話,你仍是應該繼續往下看看,瀏覽器
咱們先開始看看,什麼叫函數表達式,而後再說一下如今調試器如何處理這些表達式函數
函數表達式和函數聲明學習
在ECMAScript中,建立函數的最經常使用的兩個方法是函數表達式和函數聲明,二者之間的區別是有點暈的,由於ECMA規範只明確了一點,函數聲明必須帶有標示符(Identifier)(就是你們常說的函數名稱),而函數表達式則能夠省略這個標示符:debug
函數聲明:調試
function 函數名稱 (參數:可選){函數體}htm
函數表達式:對象
function 函數名稱(可選)(參數:可選){函數體}blog
因此,能夠看出,若是不聲明函數名稱,它確定是表達式,可若是聲明瞭函數名稱的話,如何判斷是函數聲明仍是函數表達式呢,ECMAScript是經過上下文來區分的,若是function foo(){}是做爲賦值表達式的一部分的話,那它就是一個函數表達式,若是funcrion foo(){}被包含在一個函數體內,或者位於程序的最頂部的話,那它就是一個函數聲明,
function foo(){} //聲明,由於他是程序的一部分
var bar =function(){} //表達式,由於她是賦值表達式的一部分
new function bar (){} //表達式,由於他是new表達式
(function(){
function bar(){} //聲明,由於它是函數體的一部分
})();
還有一種函數表達式不太常見,就是被括號擴住的(function foo(){}),他是表達式的緣由是由於括號()是一個分組操做符,它的內部只能包含表達式,咱們來看幾個例子:
function foo(){} //函數聲明
(function foo(){});//函數表達式:包含在分組操做符內
try{
(var x=5); //分組操做符,只能包含表達式不能包含語句:這裏的var就是語句
}catch(err){
//syntaxError
}
你能夠會想到,在實用eval對json進行執行的時候,json字符串一般被包含在一個圓括號裏:eval('('+json+')'),這樣作的緣由就是由於分組操做符,也就是這對括號,會讓解析器強制將json的花括號解析成表達式而不是代碼塊。
try{
{'x':5} //'{'和'}'作解析成代碼塊
}catch(err){
// SyntaxError
}
({'X':5});//分組操做符強制將‘{’ 和 ‘}’做爲對象字面量來解析
表達式和聲明存在着十分微妙的差異,首先,函數聲明會在任何表達式被解析和求值以前先被解析和求值,即便你的聲明在代碼的最後一行,它也會在同做用域內第一個表達式以前被解析/求值,參考以下例子,函數fn是在alert以後聲明的,可是alert執行的時候,fn已經有定義了:
alert(fn());
function fn(){
return 'hello world';
}
另外還有一點須要提醒一下,函數聲明在條件語句內雖然能夠用,可是沒有被標準化,也就是說不通同的環境可能有不通的執行結果,因此這樣狀況下,最好使用函數表達式:
//千萬別這樣作
//由於有的瀏覽器會返回first的這個function,而有的瀏覽器返回的倒是第二個
if(true){
function foo(){
return 'first';
}
}else{
function foo(){
return 'second';
}
}
foo();
//相反,這樣狀況,咱們要用函數表達式
var foo;
if(true){
foo=function(){
return 'first';
}
}else{
foo=function(){
return 'second';
}
}
foo();
函數聲明的實際規範以下:
函數聲明只能出如今程序或函數體內。從句法上講,他們不neng出如今block(塊)({...})中,例如不能出如今if、while、或for語句中。由於block(塊)中只能包含statement語句,而不能包含函數聲明這樣的源元素。另外一方面,仔細看一看規則也會發現,惟一可能讓表達式出如今block中的情形,就是讓它做爲表達式語句的一部分,到那時,規範明確規定了報答是語句不能以關鍵字functionkaitou,而這實際上就是說,函數表達式一樣不能出如今statement語句貨bloak中,由於block就是由statemengt語句構成的 gtfgg