JS闭包——总结本人对JS函数闭包的理解(面试重点)

闭包

闭包的概念: 闭包是由函数及声明该函数的词法环境组成的现象,这种现象在JS中无处不在。

闭包的例子:

function myFunc1() {
    var a=10;
    function myFunc2() {
        alert(a);   
    }
    return myFunc2;
}

这是我们日常最常见的闭包现象:一个函数在另一个函数内部声明,并且被外部函数返回。
在这个例子中,函数myFunc2与函数myFunc1所形成的上下文,共同形成了闭包。

闭包的作用:

  • 在函数内访问另一个函数内声明的变量

上例中,在内函数myFunc2中可以访问myFunc1中的变量a. 这是两个并列声明的函数做不到的,这是闭包的作用之一,即:在函数内部可以访问另一个函数所声明的局部变量
需要注意的是,由于内函数是在外函数里声明的,所以内函数相当于外函数的局部变量。当我们想在外部使用内函数之前,必须经过两个步骤:

  1. 外函数至少执行一次。(即声明变量a和定义内函数)
  2. 内函数必须以某种方式保存起来,以保证外部有办法访问的到。

保存内函数
  第一种方式就是把内函数在外函数内部赋给一个全局变量。

var N;
function myFunc1() {
    var a=10;
    function myFunc2() {
        console.log(a);   
    }
   N = myFunc2;
}

myFunc1();  //外函数至少执行一次
N(); //输出10

  第二种方式就是将内函数以外函数返回值形式保存

function myFunc1() {
    var a=10;
    function myFunc2() {
        alert(a);   
    }
    return myFunc2;
}
var myFunc = myFunc1();  //执行外函数并保存内函数
myFunc(); //弹出10
  • 用闭包模拟私有方法:

  在典型的面对对象编程语言中(如Java)中都支持私有方法,即此方法只能被定义它的类中的其他方法所调用,在JavaScript中没有私有方法这个概念。但是我们可以用闭包模拟实现私有方法,看下面的例子:

var add = function(){
  var number = 0;
  function cnumber(a){
    number = number+a;
  }
  return {   //函数返回一个对象
    increment:function(){
      cnumber(1);
    },
    decrement:function(){
      cnumber(-1);
  },
   getNumber:function(){
      console.log(number);
    },
  }
}

var mo =add();    //执行函数,并把返回值赋给mo,number = 0;
mo.increment();  //调用增函数,number = 1;
mo.increment();//number = 2;
mo.increment();//number = 3;
mo.decrement(); //调用减函数,number = 2;
mo.getNumber();   //输出2

mo = add();    //再次调用函数add,并赋给mo,刷新number值,实现复位
mo.getNumber();  //输出0

  在这个例子我们实现了一个简单的计数器,它支持加,减,复位,输出功能。
  我们首先定义了一个add函数(外围函数),里面的cnumber函数处于add函数的创建作用域中,可以作为私有函数 被返回的对象中的方法反复调用,以达到对变量number值的修改,最后调用getNumber方法弹出变量add. 这个例子中无处不是闭包,体现了闭包的强大之处。而这种模式在JS中也被称为模块

使用闭包时应注意:

  1. 外层函数调用后,外层函数的函数作用域里的变量被内层函数引用着,导致变量无法被JS垃圾回收机制回收,因此,如果在程序中滥用闭包,将会非常消耗内存,可能会造成内存泄漏。

    解决办法: 在外层函数执行到最后时,我们应该手动回收变量。具体办法就是给变量赋于null值。

  2. 闭包会在父函数外部,改变父函数内部变量的值。

    解决办法: 如果你把父函数当作对象使用,把闭包当作它的公用方法,把内部变量当作它的私有属性,这时一定要小心,不要随便改变父函数内部变量的值。这可能会造成一些难以察觉的错误。

你可能感兴趣的:(JavaScript)