函数参数默认值、递归、预编译、暗示全局变量
目录
函数默认值
递归基础和预编译
一、函数默认值
- 函数形参的默认值是undefined
- 可以给形参赋值,ES6新增
// 形参赋值
function test(a = 2, b) {
console.log(a); // 2
console.log(b); // undefined
}
test(1);
- 可以给函数形参设置保底值
// 函数形参设置保底值
function test(a, b) {
var a = arguments[0] || 1;
var b = arguments[1] || 2;
console.log(a + b); // 3
}
test();
二、递归基础和预编译
什么时候使用递归
- 找到方法的规律,按照这个规律一层一层调用自己,必须要设置一个出口,否则会死循环
- 设置出口时的值一定要是确定的,这个值会一层一层往上合并计算最后返回结果
//n的阶乘递归实现
// fact(n)
// n! = n * (n-1)! 规律
// 出口
function fact(n) {
if (n === 1) {
return 1;
}
return n * fact(n - 1);
}
// n = 5
// fact(5) = 5 * fact(5-1) = 5 * 24
// fact(4) = 4 * fact(4-1) = 4 * 6
// fact(3) = 3 * fact(3-1) = 3 * 2
// fact(2) = 2 * fact(2-1) = 2 * 1
// fact(1) return 1 然后往上一层一层的回归
// 最终return 出120
// 斐波拉契数列递归实现
// 斐波拉契数列规律:n3 = n2 + n1;
// 出口: n <= 0 or n <= 2
function fb(n) {
if (n <= 0) {
return 0;
}
if (n <= 2) {
return 1;
}
return fb(n - 1) + fb(n - 2);
}
// n = 5
// fb(5) = fb(4) + fb(3) fb(5) = 3 + 2 = 5
// fb(4) = fb(3) + fb(2) fb(4) = 2 + 1 = 3
// fb(3) = 1 + 1 // fb(3) = 1 + 1 = 2
// 递归的规律是: 1. 找到规律,2. 找到函数的出口要能结束
预编译原理
- 首先,JS引擎检查通篇的语法是否有错误
- 随后开始预编译的过程
- 第二步,解释一行执行一行
- 预编译会对var声明的变量和全局函数进行提升(存到GO内)
- 预编译不看判断语句,只看变量和函数声明
暗示全局变量
- 如果只赋值,不声明,那这个变量就是全局变量,会保存到window内
- let 和 const 没有变量提升
AO
-
全称为activation object 活跃对象,函数上下文
-
流程为:
- 寻找形参和变量声明
- 实参值赋值给形参
- 如果函数内还有函数声明则找到并赋值
- 执行函数
GO
-
全称为 global object 全局上下文
-
流程为:
- 找var声明的变量
- 找函数声明
- 执行上下文
-
GO = window
三、课后习题
习题1
function test() {
return a;
a = 1;
function a() {}
var a = 2;
}
console.log(test()); // function a
// 预编译过程
/* GO{
test: function test(){},
}
AO{
a: undefined,
function a(){}
} */
习题2
function test() {
a = 1;
function a() {}
var a = 2;
return a;
}
console.log(test()); //2
// 预编译过程
/* GO{
test: function test(){},
}
AO{
a: undefined,
function a(){}
1
2
} */
习题3
a = 1;
function test(e) {
function e() {}
arguments[0] = 2;
console.log(e); //2
if (a) {
var b = 3;
}
var c;
a = 4;
var a;
console.log(b); //undefined
f = 5;
console.log(c); //undefined
console.log(a); // 4
}
var a;
test(1);
// 预编译过程
/* GO{
a: undefined -> 1,
test: function test(){},
f: undefined -> 5
}
AO{
e: undefined -> 1 -> function e(){} -> 2
b: undefined,
c: undefined,
a: undefined -> 4,
} */
\