定义函数的方式有两种:一种是函数声明,另一种是函数表达式

一、两者的语法

函数声明的语法:

function functionName(arg0, arg1, arg2){
        //函数体      
}

函数表达式的语法:

var functionName = function(arg0, arg1, arg2){
        //函数体  
}

因为function关键字后面没有标识符,这种情况下创建的函数叫做匿名函数(anonymous function,有时也叫拉姆达函数)。匿名函数的name属性是空字符串。

二、两者区别  

在ECMAScript中,有两个最常用的创建函数对象的方法,即使用函数表达式或者使用函数声明。对此,ECMAScript规范明确了一点,即是,即函数声明 必须始终带有一个标识符(Identifier),也就是我们所说的函数名,而函数表达式则可以省略。

  关于函数声明,它的一个重要特征就是函数声明提升(function declaration hoisting),意思是在执行代码之前会先读取函数声明。这就意味着可以把函数声明放在调用它的语句的后面。

sayHi();
function sayHi(){
        alert("Hi");      
}

而函数表达式与其他表达式一样,在使用前必须先赋值。以下代码就会发生错误。

sayHi();
var sayHi = function(){
        alert("Hi!");  
}

三、两者的转换

为了提高开发效率,开发者会使用IFEE(immediately-invoked function expression,即时执行方法

那么为什么要 IIFE?

  1. 传统的方法啰嗦,定义和执行分开写;
  2. 传统的方法直接污染全局命名空间(浏览器里的 global 对象,如 window

传统的写法:

function foo() {...}     // 这是定义,Declaration;定义只是让解释器知道其存在,但是不会运行。

foo();                   // 这是语句,Statement;解释器遇到语句是会运行它的。

IIFE的写法:

(function foo() {...})    // 这里是故意换行,实际上可以和下面的括号连起来
();

以上就是将函数声明变成了表达式,即把函数声明用一对 () 包裹起来

这就等价于:

var foo = function () {...};    // 这就不是定义,而是表达式了。
foo();

除此之外,转变表达式的办法还是很多的。边学习边补充。