1、概念

闭包函数:申明在一个函数中的函数,叫做闭包函数。

闭包:外部函数总是能够拜访其所在的内部函数中申明的参数和变量,即便在其内部函数被返回(寿命终结)了之后。

2、特点

让内部拜访函数外部变量成为可能;

局部变量会常驻在内存中;

能够防止应用全局变量,避免全局变量净化;

会造成内存透露(有一块内存空间被长期占用,而不被开释)

3、闭包的创立:

闭包就是能够创立一个独立的环境,每个闭包外面的环境都是独立的,互不烦扰。闭包会产生内存透露,每次内部函数执行的时 候,内部函数的援用地址不同,都会从新创立一个新的地址。但但凡以后流动对象中有被外部子集援用的数据,那么这个时候,这个数据不删除,保留一根指针给外部流动对象。

闭包内存透露为: key = value,key 被删除了 value 常驻内存中; 局部变量闭包升级版(两头援用的变量) => 自在变量;

4、闭包的利用场景

论断:闭包找到的是同一地址中父级函数中对应变量最终的值

最终秘诀就这一句话,每个例子请自行带入这个论断!!!!!!!!!!!!!

/ 例子1 /

function funA(){  var a = 10;  // funA的流动对象之中;  return function(){   //匿名函数的流动对象;        alert(a);  }}var b = funA();b();  //10

/ 例子2 /

function outerFn(){  var i = 0;   function innerFn(){      i++;      console.log(i);  }  return innerFn;}var inner = outerFn();  //每次内部函数执行的时候,都会开拓一块内存空间,内部函数的地址不同,都会从新创立一个新的地址inner();inner();inner();var inner2 = outerFn();inner2();inner2();inner2();   //1 2 3 1 2 3

/ 例子3 /

var i = 0;function outerFn(){  function innnerFn(){       i++;       console.log(i);  }  return innnerFn;}var inner1 = outerFn();var inner2 = outerFn();inner1();inner2();inner1();inner2();     //1 2 3 4

/ 例子4 /

function fn(){    var a = 3;    return function(){        return  ++a;                                         }}alert(fn()());  //4alert(fn()());  //4    

/ 例子5 /

function outerFn(){var i = 0;  function innnerFn(){      i++;      console.log(i);  }  return innnerFn;}var inner1 = outerFn();var inner2 = outerFn();inner1();inner2();inner1();inner2();    //1 1 2 2

/ 例子6 /

(function() {   var m = 0;   function getM() { return m; }   function seta(val) { m = val; }   window.g = getM;   window.f = seta; })(); f(100);console.info(g());   //100  闭包找到的是同一地址中父级函数中对应变量最终的值

/ 例子7 /

function a() {   var i = 0;   function b() { alert(++i); }   return b; } var c = a(); c();      //1 c();      //2 

/ 例子8 /

function f() {   var count = 0;   return  function() {       count++;       console.info(count);   } } var t1 = f();t1();     //1 t1();     //2 t1();     //3 

/ 例子9 /

var add = function(x) {   var sum = 1;   var tmp = function(x) {       sum = sum + x;       return tmp;      }   tmp.toString = function() {       return sum;   }  return tmp; } alert(add(1)(2)(3));     //6

/ 例子10 /

var lis = document.getElementsByTagName("li");for(var i=0;i<lis.length;i++){  (function(i){      lis[i].onclick = function(){           console.log(i);      };  })(i);       //事件处理函数中闭包的写法}  

/ 例子11 /

function m1(){     var x = 1;     return function(){          console.log(++x);     }} m1()();   //2m1()();   //2m1()();   //2 var m2 = m1();m2();   //2m2();   //3m2();   //4

/ 例子12 /

var  fn=(function(){   var  i=10;   function  fn(){      console.log(++i);   }   return   fn;})() fn();   //11fn();   //12

/ 例子13 /

function love1(){     var num = 223;     var me1 = function() {           console.log(num);     }     num++;     return me1;}var loveme1 = love1();loveme1();   //输入224

/ 例子14 /

function fun(n,o) {    console.log(o);    return {         fun:function(m) {               return fun(m,n);         }    };}var a = fun(0);  //undefineda.fun(1);  //0  a.fun(2);  //0  a.fun(3);  //0  var b = fun(0).fun(1).fun(2).fun(3);   //undefined  0  1  2var c = fun(0).fun(1);  c.fun(2);  c.fun(3);  //undefined  0  1  1

/ 例子15 /

function fn(){   var arr = [];   for(var i = 0;i < 5;i ++){     arr[i] = function(){         return i;     }   }   return arr;}var list = fn();for(var i = 0,len = list.length;i < len ; i ++){   console.log(list[i]());}  //5 5 5 5 5

/ 例子16 /

function fn(){  var arr = [];  for(var i = 0;i < 5;i ++){    arr[i] = (function(i){        return function (){            return i;        };    })(i);  }  return arr;}var list = fn();for(var i = 0,len = list.length;i < len ; i ++){  console.log(list[i]());}  //0 1 2 3 4