1. 参数默认值

  • ES6新特性,老版本浏览器(IE8)不支持
  • 参数的默认值,未设置时,为undefined
  • 形参默认值设置 function(a = 1, b = 2) {};
  • 参数值的映射:

    • 对于某一个参数,若默认值和传入的实参值都为undifined,才为undefined
    • 若其中一个不是undefined,则使用该值
    • 若两个都不为undefined,则使用实参值
      1. function test (a = 1, b) {
      2. //...
      3. }
      4. // 要求:a保持默认值,b=2
      5. test(undefined, 2);
      1. // ES5
      2. function test(a, b) {
      3. // var a = arguments[0] || 1;
      4. // var b = arguments[1] || 2;
      5. var a = typeof(arguments[0]) === 'undefined' ? 1 : arguments[0];
      6. var b = typeof(arguments[1]) === 'undefined' ? 2 : arguments[1];
      7. console.log(a, b)
      8. }

      2. 递归

  • 函数自己调用自己

  • 两大要素
    1. 规律
    2. 出口

      案例1. 求n的阶乘

      1. function factorial(n, f) {
      2. if(n < 0) throw new Error("参数必须大于或等于0")
      3. if(n === 1 || n === 0) return 1;
      4. return n * factorial(n - 1);
      5. }

      案例2. 求第n位斐波那契数列的值

      1. function fibonacci(n) {
      2. if(n < 0) throw new Error("参数必须大于或等于0")
      3. if(n === 0) return 0;
      4. if(n === 1) return 1;
      5. return fibonacci(n - 1) + fibonacci(n - 2);
      6. }

      3. 预编译

      3.1 预编译在JS引擎工作流程中的位置

  1. 先通篇检查语法错误 SyntaxError
  2. 预编译
  3. 解释一行,执行一行

3.2 函数 vs 变量

  • 函数声明赋值整体提升
  • 变量只有声明提升,赋值不提升


3.3 暗示全局变量 imply global

在全局,无论是否使用var声明,变量都定义在window对象上
var a; // a = window.a

  1. function test() {
  2. var a = b = 1;
  3. }
  4. test();
  5. console.log(b); // -> 1; b 并没有在test()内部声明
  6. console.log(a); // -> ReferenceError

3.4 函数预编译 与 执行期上下文-AO

函数预编译步骤:

  1. 创建AO对象 (activation object ,执行期上下文/函数上下文) AO = {}
  2. 寻找函数的形参和变量声明
  3. 把实参值赋给形参
  4. 寻找函数声明,赋值函数体
  5. 逐行执行函数代码,预编译执行过的代码行直接跳过

    例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(){}, }

  1. <a name="HbJDZ"></a>
  2. #### 例2:
  3. ```javascript
  4. function test(a, b) {
  5. console.log(a); // -> 1
  6. c = 0;
  7. var c;
  8. a = 5;
  9. b = 6;
  10. console.log(b); // -> 6
  11. function b(){};
  12. function d(){};
  13. console.log(b); // -> 6
  14. }
  15. test(1);
  16. console.log(a, b, c);
  17. AO = {
  18. a: undefined -> 1 -> 5,
  19. b: undefined -> function b(){} -> 6,
  20. c: undefined -> 0,
  21. d: function d(){}
  22. }

3.4 全局预编译 与 全局上下文-GO

全局预编译的步骤:

  1. 创建GO对象 (global object ,全局上下文/函数上下文) GO = {}
  2. 寻找变量声明 var
  3. 寻找函数声明 function
  4. 逐行执行代码,预编译执行过的代码行直接跳过

*GO在浏览器中就是window对象

例1:

  1. var a = 1;
  2. function a() {
  3. console.log(2);
  4. }
  5. console.log(a); // -> 1
  6. GO = {
  7. a: undefined -> function a(){} -> 1
  8. }

3.5 综合 GO & AO

例1:

  1. function test() {
  2. var a = b = 1;
  3. }
  4. test()
  5. GO = {
  6. b: 1
  7. }
  8. AO = {
  9. a: undefined -> 1
  10. }

例2:

  1. var b = 3;
  2. console.log(a); // -> function a(a){...}
  3. function a(a) {
  4. console.log(a); // -> function a() {}
  5. var a = 2;
  6. console.log(a); // -> 2
  7. function a() {}
  8. var b = 5;
  9. console.log(b) // -> 5
  10. }
  11. a(1);
  12. GO = {
  13. b: undefined -> 3;
  14. a: function a(a){...}
  15. }
  16. AO = {
  17. a: undefined -> 1 -> function a() {} -> 2,
  18. b: undefined -> 5
  19. }

例3:

  1. a = 1;
  2. function test(){
  3. console.log(a); // undefined
  4. a = 2;
  5. console.log(a); // 2
  6. var a = 3;
  7. console.log(a); // 3
  8. }
  9. test();
  10. var a;
  11. GO = {
  12. a: undefined -> 1,
  13. test: function test(){...}
  14. };
  15. AO = {
  16. a: undefined -> ,
  17. }

例4:

  1. function test() {
  2. console.log(b); // -> undefined
  3. if(a) {
  4. var b = 2;
  5. }
  6. c = 3;
  7. console.log(c); // -> 3
  8. }
  9. var a;
  10. test();
  11. a = 1;
  12. console.log(a); // -> 1
  13. GO = {
  14. a: undefined -> 1,
  15. test: function test() {},
  16. c: 3
  17. }
  18. AO = {
  19. b: undefined,
  20. }

例5:

  1. function test() {
  2. return a;
  3. a = 1;
  4. function a(){};
  5. var a = 2;
  6. }
  7. console.log(test());
  8. AO = {
  9. a: undefined -> function a() {},
  10. }
  11. GO = {
  12. test: function test() {},
  13. }

例6:

  1. function test() {
  2. a = 1;
  3. function a() {};
  4. var a = 2;
  5. return a;
  6. }
  7. console.log(test());
  8. GO = {
  9. a: 1,
  10. }
  11. AO = {
  12. a: undefined -> function a() {} -> 1 > 2
  13. }

例7:

  1. a = 1;
  2. function test(e) {
  3. function e() {}
  4. arguments[0] = 2;
  5. console.log(e); // -> 2
  6. if(a) {
  7. var b = 3;
  8. }
  9. var c;
  10. a = 4;
  11. var a;
  12. console.log(b); // -> undefined
  13. f = 5;
  14. console.log(c); // -> undefined
  15. console.log(a); // -> 4
  16. }
  17. var a;
  18. test(1);
  19. console.log(a); // -> 1
  20. console.log(f); // -> 5
  21. GO = {
  22. a: undefined -> 1,
  23. test: function test() {},
  24. f: 5
  25. }
  26. AO = {
  27. e: undefined -> 1 -> function e() {} -> 2,
  28. b: undefined,
  29. c: undefined,
  30. a: undefined -> 4,
  31. }