湯姆大叔的博客(深刻理解JavaScript系列(2):揭祕命名函數表達式)

湯姆大叔的博客,本人學習階段,寫不出經典的東西,只能抄襲,可是本人尊重原創,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

相關文章
相關標籤/搜索