0. 函数式编程
函数(的声明)是一个固定的功能或者程序段被封装的过程
为了实现一个固定的功能或程序,这个封装体需要提供一个入口和一个出口,入口就是函数的参数,出口就是函数的返回值
1. 函数的声明
1.1 方式一 function
声明
- 匿名函数表达式、函数字面量
var test = function() { };
- 具名函数表达式:
var test = function test1() {};
var aa = 2, bb = 3;
test(aa, bb)
<a name="mieCe"></a>
## 2.1 形参与实参的概念
- a, b 为形参,用于形式上的占位。
- aa, bb 为实参,实际调用时分别赋值给a, b
- 形参可以看作定义在函数中的变量,在函数调用时再将传入的实参赋值给对应的形参
<a name="V6L56"></a>
## 2.2 形参与实参的个数问题
- 形参和实参数量可不等
- 实参可在函数运行时通过`函数名.arguments`变量获取
- arguments 为数组类型,可使用`arguments[index]`获取每个位置上的形参
- arguments.length即为实参的个数
- 形参个数可以通过`函数名.length`获取
<a name="O0Pi7"></a>
## 2.3 形参与实参的映射
- 形参变量与实参arguments数组中对应位置的值并不是同一个变量(形参储存在栈内存,而实参数组储存在堆内存中)
- 若函数调用时,第i个位置的参数传入了值,则`arguments[i]`有值。此时`arguments[i]`与第i个形参具有映射关系,第i个形参值改变时,`arguments[i]`的值也会发生相应的变化。
- 若函数调用时,第i个位置的参数未传入值,则`arguments[i]`不存在或为undefined。此时i,`arguments[i]`与第i个形参无映射关系,不会随着形参值的变化而变化
<a name="nPCPl"></a>
## 2.4 函数的return
<a name="RanGl"></a>
### 2.4.1 作用一:终止函数的执行
- 函数执行到return语句时,结束执行
- return语句后面的语句都不执行
- 函数体中不存在return语句时,JS引擎会在函数体末尾自动添加return语句
<a name="xaJCg"></a>
### 2.4.2 作用二:返回函数执行的结果
<a name="zEOLL"></a>
## 2.5 函数作为局部作用域(作用域初识
- 函数(局部作用域)内部可读取 外部 / 全局作用域 内的变量
- 局部作用域中定义的变量在外部作用域中 是不可见的
```javascript
a = 1; // 全局变量
function test1() {
var b = 2; // 函数test1作用域内的局部变量
console.log(a, b); // -> 1, 2
function test2() {
var c = 3; // 函数test2作用域内的局部变量
console.log(a, b, c); // -> 1, 2, 3
}
test2();
console.log(c); // 报错,c未定义
}
test1();
console.log(b, c); // 报错,b,c未定义
案例:
1. 累加函数(实参个数不确定)
function sum() {
var s = 0;
for (var i = 0; i < sum.arguments.length; i++) {
s += sum.arguments[i];
}
return s
}
sum(1, 2, 3, 4, 5);
2. 编写函数求n的阶乘(不能用for循环)
// 1. 规律
// 2. 出口
function factorial(n, f) {
if(n === 1) return 1;
return n * factorial(n - 1);
}
3. 编写函数求第n位斐波那契数列的值(不能用for循环)
function fibonacci(n) {
if(n === 0) return 0;
if(n === 1) return 1;
return fibonacci(n - 1) + fibonacci(n - 2);
}