汤姆大叔的博客(深刻理解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

相关文章
相关标签/搜索