JavaScript闭包(closure)

一、概述

 什么是闭包?MDN中第一句话就是

A closure is the combination of a function and the lexical environment within which that function was declared

 也就是说closure=function+lexical environment,lexical environment即是function声明的地方,然而这并不容易理解,或者说有点概念化,之后又参考了几篇文章,终于初步理解了闭包。

二、常见闭包

 我们通常见到的闭包往往是这样的,例一:

function exam(){
  var a=3
  function fn(){  //closure
     alert(a)
  }
 fn()
}

 也就是说闭包常以函数嵌套的方式出现,但是根据闭包的定义,以下例子也是闭包,例二:

var a=3
function(){  //closure
  return a
}

 那么为什么我们常见的是第一种嵌套函数样式的闭包呢?原因就在于闭包的用途,我们有时需要隐藏一个变量,但是又不能完全不可引用,这个时候就用到了闭包。
 如同例一中的a,在全局环境中本无法直接访问到,但是我们通过闭包,外界环境就可以访问到a,这里exam()的存在事实上只是使a变成了局部变量而已,也就是说,例三:

!function(){
  a=3
  function fn(){
    alert(a)
  }
  fn()
}()

 使用一个立即执行的外层函数实际上可以达到同样的效果。

三、重要特性

 闭包有一个重要特性,即是状态的保持,我们知道,普通函数是不会保存状态的,如,例四:

function fn(){
  var a=0;
  console.log(++a);    
}
fn();  //1
fn();  //1
fn();  //1

 显然,这里的fn函数无论调用多少次都是输出1,下一个例子,例五:

function fn(){
  var a=0;
  return function(){  //closure
    console.log(++a);   
  }
}
var aFn=fn();
aFn();  //1
aFn();  //2
aFn();  //3

 例五中每调用一次,原来的a就加了1,这就说明原来的fn中return的匿名函数的所处环境被保留了(即使此时fn本身已经被清除了),说明aFn自己保持了他所处环境(lexical environment)的引用。

四、总结

 说了这么多我感觉概念性的东西太容易把人绕晕,可能我们经常在使用它的时候反而没那么在意闭包的概念,值得一提的是个人认为闭包的状态保持是一个很有意思的东西。

你可能感兴趣的:(JavaScript闭包(closure))