导言
在这篇文章中,我们将更详细的讨论一个常见的ECMAScript对象——函数。我们将详细地研究函数的各种类型,解释这种或那种类型的函数如何影响一个上下文的变量对象以及函数某一个类型的作用域链中包含什么。我们将回答论坛中像这样经常被问及的问题:“下面创建的函数与以一种“习惯的方式”定义的函数之间有什么区别(如果有,是什么?)”(注:原文的顺序不是这样,本人作了调整)
var foo = function () { ...};
以一种“习惯的方式”定义的函数:
function foo() { ...}
或者,“为什么下面的函数调用应该用圆括号包围?”
(function () { ...})();
因为这些文章独立于早期的章节,由于我们会积极地使用来自这些章节的语法,为了全面理解这一部分,如有必要,值得去读第二章:变量对象和第四章:作用域链。
但是让我们一个个接着来,首先从函数的类型研究起。
函数类型
在ECMAScript 中有三种函数类型,每一种都有自己的特点。
函数声明
函数声明(缩写为FD)是这样一种函数:
function exampleFunc() { ...}
这种函数类型的主要特点在于它们仅仅影响变量对象(即函数存储在上下文的VO中)。该特点也解释了第二个重要点(它是变量对象特性的结果)——在代码执行阶段它们已经可用(因为FD在进入上下文阶段已被VO收集)。
例如(源码中函数在其声明之前被调用)
foo();function foo() { alert('foo');}
同样一个重要点是定义中的第二点——源码中函数声明的位置:
// function declaration// is directly in:// either the global context// at Program levelfunction globalFD() { // or directly inside the body // of another function function innerFD() {}}
在代码中的任何其他位置,函数声明不能出现——即,不可能在表达式位置或一个代码块中定义它。
取代函数声明(更有可能认为是与之相对)的是函数表达式。