导言
本章学习内容:
- 函数表达式的特征
- 使用函数实现递归
- 使用闭包定义私有变量
函数表达式是javaScript中的一个既强大又容易令人困惑的特征。我们知道定义函数的方式有两种:
- 函数声明
- 函数表达式
而函数声明的语法是这样的
function functionName(arg1,arg2) {
// 函数体
}
通过name 属性可以访问到函数指定的名字。
functionName.name // 'functionName'
关于函数声明,它的一个重要特征就是函数声明提升,意思是在执行代码之前会先读取函数声明。这就意味着可以把函数声明放在调用它的语句后面。
say();
function say() {
console.log('hello')
}
另一种创建函数的方式是使用函数表达式
var functionName = function(arg0,arg1) {
// 函数体
}
这种情况下创建的函数叫做匿名函数,因为function 关键字后面没有标识符。
理解函数提升的关键,就是理解函数声明与函数表达式之间的区别。
例如,执行以下代码的结果可能会让人意想不到:
// 不要这样做
if(condition) {
function sayHi() {
console.log('Hi')
}
} else {
function sayHi() {
console.log('Yo')
}
}
递归
递归函数在一个函数通过名字调用自身的情况下构成的.
function factor(num) {
if(num <= 1) {
return 1;
} else {
return num * factor(num - 1);
}
}
这个一个经典的递归阶乘函数。但是可能有有点问题。
var anthor = factor;
factor = null;
anthor(4); // 出错
在这种情况下,使用 arguemnts.callee 可以解决这个问题。
arguments.callee是一个指向正在执行的函数的指针,因此可以用它来实现对函数的递归调用
function factor(num) {
if(num < 1) {
return 1;
} else {
return num * arguments.callee(num - 1);
}
}
闭包
闭包是指有权访问另一个函数作用域中的变量的函数。
创建闭包的常见方式,就是在一个函数内部创建另一个函数,仍以前面的实例为主:
function createComparisonFunction(propertyName) {
return function(object1,object2) {
var value1 = object1[propertyName];
var value2 = object2[propertyName];
if(value1 < value2) {
return -1;
} else if(value2 < value1) {
return 1;
} else {
return 0;
}
}
}