复习JavaScript 2

  二、揭秘命名函数表达式

  1、函数表达式和函数声明

函数声明:

function 函数名称 (参数:可选){ 函数体 }

  函数表达式:

function 函数名称(可选)(参数:可选){ 函数体 } 

function foo(){} // 声明,因为它是程序的一部分
  var bar = function foo(){}; // 表达式,因为它是赋值表达式的一部分

  new function bar(){}; // 表达式,因为它是new表达式

  (function(){
    function bar(){} // 声明,因为它是函数体的一部分
  })();

  到底什么是表达式?

  《JavaScript语言精粹》这样描述:

所以如下是函数表达式。

(function foo(){})

  2、函数声明与函数表达式的区别

首先,函数声明会在任何表达式被解析和求值之前先被解析和求值,即使你的声明在代码的最后一行,它也会在同作用域内第一个表达式之前被解析/求值,参考如下例子,函数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();

函数声明的实际规则如下:

函数声明只能出现在程序函数体内。从句法上讲,它们 不能出现在Block(块)({ ... })中,例如不能出现在 if、while 或 for 语句中。因为 Block(块) 中只能包含Statement语句, 而不能包含函数声明这样的源元素。另一方面,仔细看一看规则也会发现,唯一可能让表达式出现在Block(块)中情形,就是让它作为表达式语句的一部分。但是,规范明确规定了表达式语句不能以关键字function开头。而这实际上就是说,函数表达式同样也不能出现在Statement语句或Block(块)中(因为Block(块)就是由Statement语句构成的)。 

(这段话有点没看懂)


感谢@汤姆大叔 的《深入理解JavaScript》系列指导我学习!

原文地址:https://www.cnblogs.com/ltchronus/p/3529119.html