函数表达式
函数表达式是JavaScript中的一个强大且令人困惑的特性。定义函数有两种方式:
- 函数声明凡是
形如
function functionName(arg0,arg1,arg2){
//函数体
}
关于函数声明,一个重要的特征就是函数声明提升,即在执行代码前会先读取函数声明。这意味着可以把函数声明放在调用它的语句之后。
- 函数表达式方式
函数表达式有几种不同的语法形式。下面是最常见的形式,即匿名函数,匿名函数的name属性是空字符串。
var functionName = function(arg0,arg1,arg2){
//函数体
}
函数表达式和其他表达式一样,在使用前必须先赋值,否则会引起错误。
递归
递归函数是在一个函数通过名字调用自身的情况下构成的,如下
function f(n){
if(n==1){
return 1;
}else{
return n*f(n-1);
}
}
这个经典的例子虽然表面上看不出问题,但是在执行下面代码时可能会出错。
var fun = f;
f = null;
alter(fun(4)); //出错!
以上代码先把函数f()保存到变量fun中,然后将f变量置为null,结果指向原始函数的引用只剩下一个。接下来调用fun()时,由于执行必须f(),而f此时已经置空,所以错误。
在这种情况下,使用可以arguments.callee,其表示一个指向正在执行的函数的指针,故而可以用它实现函数的递归调用,如:
function f(n){
if(n==1){
return 1;
}else{
return n*arguments.callee(n-1);
}
}
但在严格模式下,不能通过脚本访问arguments.callee,访问这个属性会导致错误。不过可以可以使用命名函数表达式来达到相同的效果,如
var fun = (function f(n){
if(n==1){
return 1;
}else{
return n*arguments.callee(n-1);
}
});
以上代码创建了一个名为f()的命名函数表达式,然后将其赋值给fun,即使将函数赋值给另一个变量,函数名字f仍然有效。