首页 > 代码库 > js 中的闭包

js 中的闭包

闭包:闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的常见方式是 在一个函数内部创建另一个函数
        (从定义上讲 js 中所有的函数都是闭包)

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

以上代码的特点:            

  1、函数b嵌套在函数a内部;
      2、函数a返回函数b。
       当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。
            闭包就是函数或代码块执行完后不回收a中占用的资源,因为a的内部函数的执行需要依赖a中的变量
            PS:全局环境的变量对象始终存在,像函数中的局部环境变量,则只在函数执行的过程中存在
            作用域链本质上是一个指向变量对象的指针列表,它只引用但不实际包含变量对象。

            PS: 由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存。过渡使用闭包可能会导致内存占用过多
            所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。           

闭包的用处: 

  a.读取函数内部的变量。

      b.让这些变量的值始终保持在内存中。           

使用闭包的注意点
  1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,
      否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

  2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,
      把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),
      这时一定要小心,不要随便改变父函数内部变量的值。

 

闭包容易造成的问题:  

function a(){
  var result = new Array();
  for (var i=0; i < 10; i++){
    result[i] = function(num){
      return function(){
        return num;
      };
    }(i); //若此处不传入 i值 运行代码后 获取的值 都是 10
  }
  return result;
}
var name = "The Window";
var object = {
  name : "My Object",
  getNameFunc : function(){
    return function(){
      return this.name;
    };
  }
};
alert(object.getNameFunc()()); //"The Window"(在非严格模式下)

object.getNameFunc()  执行后 返回的是一个函数  后面的括号又运行了该函数 相当于该函数是在全局环境中运行的。

在全局环境中this 默认指向的是window对象

所以函数里面的this.name  就是全局的变量name

解决办法:

我们知道,闭包的一个作用就是读取函数内部的变量。

如果要获取本来的对象 可以将本来的this 保存在另一个自定义的变量中 然后将该变量传入返回的函数里面。

这样该变量就会一直保存在内存中 不会被销毁

 

js 中的闭包