函数表达式

定义函数方式

  1. 函数声明
function fun() {}
  1. 函数表达式
var fun = function () {};

关键词

函数声明提升

执行代码前会先读取函数声明,所以在函数声明前也可以调用函数

test();
function test() {
  alert("test");
}
// ok

匿名函数(lambda 函数)

函数表达式同其他表达式,使用前需先声明,否则报错

test();
function test() {
  alert("test");
}
// 报错

递归

经典阶乘

function factorial(num) {
  if (num <= 1) {
    return 1;
  } else {
    return num * factorial(num - 1);
  }
}

如下会使这个函数报错

// 把factorial()函数保存在another变量中
var another = factorial;
// 把变量factorial置空
factorial = null;
// 调用another()必须执行factorial(),而factorial不再是函数
alert(another(4));

解决:使用arguments.callee(指向正在执行的函数的指针)

function factorial(num) {
  if (num <= 1) {
    return 1;
  } else {
    return num * arguments.callee(num - 1);
  }
}

结论:使用递归函数,通过arguments.callee替代函数名更保险

特例:严格模式下无法通过脚本访问arguments.callee

方案:使用命名表达式(适用于严格和非严格模式)

var factorial = function f(num) {
  if (num <= 1) {
    return 1;
  } else {
    return num * f(num - 1);
  }
};

对比不适用命名表达式的情况

var factorial = function (num) {
  if (num <= 1) {
    return 1;
  } else {
    return num * factorial(num - 1);
  }
};

创建了名为 f()的命名函数表达式,并将其赋值给 factorial,这样尽管把函数赋值给其他变量,函数名 f 仍有效