函数闭包

函数表达式
  函数声明:(函数声明提升)
    function person(){}
  函数表达式:(必须在调用之前声明)
    var person = function(){}

  递归函数:
    一个函数通过名字调用自身

    function fac (num) { // 阶乘递归
      if (num <=1) {
        return 1
      } else {
        return num*fac(num-1);
      }
    }

    var a = fac;
    fac = null;
    console.log(a(4)) ; // 出错 因为fac在函数中调用自身时fac = null

  为了做到松耦和:
    非严格模式下使用argument.callee(指向正在执行的函数指针)来解决。
    function fac (num) { // 阶乘递归
      if (num <=1) {
        return 1
      } else {
        return num*argument.callee(num-1); /
      }
    }

  另一种方式:
    var ff = (function f(num){
      if (num <=1) {
        return 1
      } else {
        return num*f(num-1); // 即使ff = null f(num-1)还是可以访问到
      }
    })

  闭包:
    定义:当一个函数内部定义了一个函数就创建了闭包,闭包有权访问包含函数内部的全部变量。

    function a () {
      var arr = [];
      for (var i = 0,i < 4, i++) {
        arr[i] = function () { // 闭包函数
          return i;
        }
      }
    }

    console.log(a()) // [4,4,4,4]
    原因是闭包函数中的i变量访问的是包含函数a中的i,循环中i的指向都是同一个i变量,等a()执行结束,i变量的值是10,所以返回的是[4,4,4,4]

  解决:
    function a () {
      var arr = [];
      for (var i = 0,i < 4, i++) {
        arr[i] = function (num) { // 闭包函数
          return num;
        }(i); // 通过传值,每次返回的num都会是i的循环值
      }
    }

  闭包的应用:
    上例是一种应用,另一种应用:特权方法,(只能通过闭包函数访问包含函数的变量和方法)。
    function Creat(){
      var arr = [];
      this.arrs = function (name) {
        arr.push(name);
        console.log(arr)
      }

    }
    var a = new Creat()
    a.arrs('zhang'); // zhang

    a.arrs('ss') ; // zhang ss

  闭包的原理:
    在后台执行环境中,闭包包含着它自己的作用域、包含函数作用域、全局作用域。通常函数作用域及其所有变量都会在函数执行完毕后销毁,但是当函数返回一个闭包,函数作用域将会存在于内存中至到闭包销毁为止

猜你喜欢

转载自www.cnblogs.com/hyf120/p/9199480.html