函数表达式与闭包

函数表达式与函数声明

函数声明提升

1
2
3
4
functionName() 
function functionName(arg0, arg1, arg2) {
//函数体
}

函数表达式

1
2
3
// 函数表达式是将一个匿名函数的值给到变量,因此只会提升变量不会提升函数
// 能够有效地防止函数提升带来的一系列问题
var functionName=function(){}

递归

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function factorial(num){ 
if (num <= 1){
return 1;
} else {
return num * factorial(num-1);
}
}
// 这个阶乘看起来没什么问题但是如果这样做:
var copyFactorial = factorial;
factorial=null;
copyFactorial(10) // 报错
// 这是由于函数内部引用的是本身的函数名,而函数名只是一个函数指针而已
// 指针一旦修改那么函数也将被改变
// 这里可以使用arguments.callee引用函数体
// 但是严格模式下arguments.callee不允许使用,所以我们使用函数表达式来解决这个问题
var factorial=function f(num){
if (num <= 1){
return 1;
} else {
return num * f(num-1);
}
}
// 此时函数名f只在这个函数内部有效,外部无法引用或者修改f,这样就能够愉快地使用递归了

彻底理解闭包

1
2
3
4
5
6
7
8
9
10
11
function compare(a,b){
return function(){
if(a>b){
return 1
}
}
}
// 当某个函数被调用时,会创建一个执行环境(execution context)及相应的作用域链。
// 然后,使用 arguments 和其他命名参数的值来初始化函数的活动对象(activation object)。但在作用域
// 链中,外部函数的活动对象始终处于第二位,外部函数的外部函数的活动对象处于第三位,……直至作
// 为作用域链终点的全局执行环境。