JavaScript高级程序设计笔记(8)-函数表达式

定义函数有两种方式:函数声明和函数表达式。
函数声明:

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

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

1
2
3
4
sayHi();
function sayHi(){
alert('Hi!');
}

函数表达式:

1
2
3
var functionName = function()(arg0, arg1, ...){
//函数体
}

形式类似常规的变量赋值语句,即创建一个函数并将它赋值给变量functionName。这种情况下创建的函数叫做匿名函数(anonymous function),因为function关键字后面灭有标识符。
函数表达式与其他表达式一样,在使用前必须先赋值。

理解函数提升的关键就是理解函数声明与函数表达式之间的区别。

递归

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function factorial(num){
if(num < 1){
return 1;
}else{
return num * factorial(num -1);
}
}

//解耦

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

使用arguments.callee虽然能够解耦,但是在严格模式下,访问这个属性会导致错误。

1
2
3
4
5
6
7
var factorial = (function f(num){
if(num < 1){
return 1;
}else{
return num * f(num - 1);
}
})

上述代码创建了一个名为f()的命名函数表达式,然后将它赋值给变量factorial。即便把函数赋值给另一个变量,函数的名字f仍然有效,所以递归调用照样能正确完成。

闭包

闭包,是值有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。

闭包与变量

作用域链的配置机制,会引出一个副作用,即闭包只能取得包含函数中任何变量的最后一个值。

1
2
3
4
5
6
7
8
9
function createFunctions(){
var result = new Array();
for(var i = 0; i < 10; i++){
result[i] = function(){
return i;
}
}
return result;
}

私有变量

严格讲,Javascript中没有私有成员概念。但有私有变量的概念。任何定义在函数中的变量,都可以认为是私有变量,因为函数外部不能访问这些变量。