1. 参数默认值
- ES6新特性,老版本浏览器(IE8)不支持
- 参数的默认值,未设置时,为undefined
- 形参默认值设置
function(a = 1, b = 2) {}; 参数值的映射:
- 对于某一个参数,若默认值和传入的实参值都为undifined,才为undefined
- 若其中一个不是undefined,则使用该值
- 若两个都不为undefined,则使用实参值
function test (a = 1, b) {//...}// 要求:a保持默认值,b=2test(undefined, 2);
// ES5function test(a, b) {// var a = arguments[0] || 1;// var b = arguments[1] || 2;var a = typeof(arguments[0]) === 'undefined' ? 1 : arguments[0];var b = typeof(arguments[1]) === 'undefined' ? 2 : arguments[1];console.log(a, b)}
2. 递归
函数自己调用自己
- 两大要素
- 规律
- 出口
案例1. 求n的阶乘
function factorial(n, f) {if(n < 0) throw new Error("参数必须大于或等于0")if(n === 1 || n === 0) return 1;return n * factorial(n - 1);}
案例2. 求第n位斐波那契数列的值
function fibonacci(n) {if(n < 0) throw new Error("参数必须大于或等于0")if(n === 0) return 0;if(n === 1) return 1;return fibonacci(n - 1) + fibonacci(n - 2);}
3. 预编译
3.1 预编译在JS引擎工作流程中的位置
- 先通篇检查语法错误 SyntaxError
- 预编译
- 解释一行,执行一行
3.2 函数 vs 变量
- 函数声明赋值整体提升
- 变量只有声明提升,赋值不提升
3.3 暗示全局变量 imply global
在全局,无论是否使用var声明,变量都定义在window对象上 var a; // a = window.a
function test() {var a = b = 1;}test();console.log(b); // -> 1; b 并没有在test()内部声明console.log(a); // -> ReferenceError
3.4 函数预编译 与 执行期上下文-AO
函数预编译步骤:
- 创建AO对象 (activation object ,执行期上下文/函数上下文)
AO = {} - 寻找函数的形参和变量声明
- 把实参值赋给形参
- 寻找函数声明,赋值函数体
- 逐行执行函数代码,预编译执行过的代码行直接跳过
例1:
```javascript function test(a) { console.log(a); // -> function a(){} var a = 1; console.log(a); // -> 1 function a(){}; // skip console.log(a); // -> 1 console.log(b); // -> undefined var b = function(){}; console.log(b); // -> function(){} function d(){}; // skip }
test(2);
AO = { a: undefined -> 2 -> function a(){} -> 1, b: undefined -> function(){}, d: function d(){}, }
<a name="HbJDZ"></a>#### 例2:```javascriptfunction test(a, b) {console.log(a); // -> 1c = 0;var c;a = 5;b = 6;console.log(b); // -> 6function b(){};function d(){};console.log(b); // -> 6}test(1);console.log(a, b, c);AO = {a: undefined -> 1 -> 5,b: undefined -> function b(){} -> 6,c: undefined -> 0,d: function d(){}}
3.4 全局预编译 与 全局上下文-GO
全局预编译的步骤:
- 创建GO对象 (global object ,全局上下文/函数上下文)
GO = {} - 寻找变量声明 var
- 寻找函数声明 function
- 逐行执行代码,预编译执行过的代码行直接跳过
例1:
var a = 1;function a() {console.log(2);}console.log(a); // -> 1GO = {a: undefined -> function a(){} -> 1}
3.5 综合 GO & AO
例1:
function test() {var a = b = 1;}test()GO = {b: 1}AO = {a: undefined -> 1}
例2:
var b = 3;console.log(a); // -> function a(a){...}function a(a) {console.log(a); // -> function a() {}var a = 2;console.log(a); // -> 2function a() {}var b = 5;console.log(b) // -> 5}a(1);GO = {b: undefined -> 3;a: function a(a){...}}AO = {a: undefined -> 1 -> function a() {} -> 2,b: undefined -> 5}
例3:
a = 1;function test(){console.log(a); // undefineda = 2;console.log(a); // 2var a = 3;console.log(a); // 3}test();var a;GO = {a: undefined -> 1,test: function test(){...}};AO = {a: undefined -> ,}
例4:
function test() {console.log(b); // -> undefinedif(a) {var b = 2;}c = 3;console.log(c); // -> 3}var a;test();a = 1;console.log(a); // -> 1GO = {a: undefined -> 1,test: function test() {},c: 3}AO = {b: undefined,}
例5:
function test() {return a;a = 1;function a(){};var a = 2;}console.log(test());AO = {a: undefined -> function a() {},}GO = {test: function test() {},}
例6:
function test() {a = 1;function a() {};var a = 2;return a;}console.log(test());GO = {a: 1,}AO = {a: undefined -> function a() {} -> 1 > 2}
例7:
a = 1;function test(e) {function e() {}arguments[0] = 2;console.log(e); // -> 2if(a) {var b = 3;}var c;a = 4;var a;console.log(b); // -> undefinedf = 5;console.log(c); // -> undefinedconsole.log(a); // -> 4}var a;test(1);console.log(a); // -> 1console.log(f); // -> 5GO = {a: undefined -> 1,test: function test() {},f: 5}AO = {e: undefined -> 1 -> function e() {} -> 2,b: undefined,c: undefined,a: undefined -> 4,}
