【红宝书】第7章.函数表达式

定义函数的方法两种

  1. 函数声明

function fnName(arg0, arg1, arg2) {

//函数体

}

重要特征:函数声明提升

  1. 函数表达式

let fnName = function(arg0, arg1, arg2) {

//函数体

}

即创建一个匿名函数(因为function关键字后面没有标识符)赋值给变量fnName

使用前必须先赋值

7.1递归

递归函数是一个函数通过名字调用自身的情况下构成的

     function fn(num) {

      if (num <= 1) {

        return 1;

      } else {

        return num * fn(num - 1);

      }

    }

但是在某些情况下会出错,如

    let fn1=fn

    fn=null

    fn1(3)

使用arguments.callee(是一个指向正在执行的函数的指针,因此可以实现对函数的递归调用)

    function fn(num) {

      if (num <= 1) {

        return 1;

      } else {

        return num * arguments.callee(num - 1);

      }

    }

但在严格模式下无法访问arguments.callee,可以使用命名函数表达式达成相同的效果

   let fn1 = function f(num) {

      if (num <= 1) {

        return 1;

      } else {

        return num * f(num - 1);

      }

    }

7.2闭包

闭包概念:有权访问另一个函数作用域中的变量的函数

    function fn(property) {

      return function(obj1, obj2) {

        let val1 = obj1[property];

        let val2 = obj2[property];

        // 做其他操作

      };

    }

执行环境、作用域、作用域链

    function compare(val1, val2) {

      if (val1 < val2) {

        return -1;

      } else {

        return 1;

      }

    }

    let result = compare(5, 10);

 

7.2.1闭包和变量

副作用:闭包只能取得包含函数中任何变量的最后一个值

可以通过创建另一个匿名函数强制让闭包的行为符合预期

7.2.2关于this对象

匿名函数的执行环境具有全局性,此this对象通常指向window

可以用let that=this重指向解决

7.2.3内存泄漏

闭包作用域链保存HTML元素,则该元素无法被销毁

在使用后重新赋值null解除引用,减少其引用数,确保正常回收其占用的内存

7.3模仿块级(私有)作用域

(function(){

// 块级作用域

})

7.4私有变量

任何在函数中定义的变量,都可以认为是私有变量

有权访问私有变量和私有函数的公有方法成为特权方法

创建特权方法的方式:

  1. 在构造函数中定义特权方法,有构造模式的缺点

    function MyObj() {

      let val = 10;

      function fn() {

        return false;

      }

      this.publicMethod = function() {

        val++;

        return fn();

      };

    }

  1. 在私有作用域中定义特权方法

7.5小结

 

猜你喜欢

转载自www.cnblogs.com/Mijiujs/p/12080364.html