您的位置:首页 > Web前端 > JavaScript

js闭包

2014-03-13 16:02 281 查看
1、什么是闭包?

  函数嵌套函数

  内部函数可以引用外部函数的参数和变量,参数和变量不会被垃圾回收机制收回

function fn1(){
var a = 5;
function fn2() {
alert(a);             //内部函数使用外部函数的变量,不会被垃圾回收机制回收
}
return fn2;
}

var c = fn1();
c();
/*
结果:5
fn1(),返回结果为fn2函数,即function fn2() { alert(a) };
c(),调用fn2函数

也可以这样写:fn1()(),fn1()=fn2
*/


2、闭包的好处?应用在哪里?

  好处:

    希望一个变量长期驻扎在内存当中

    避免全局变量的污染

    私有成员的存在

/*全局变量*/
var a = 1;
function fn(){
a++;
alert(a);
}
fn();   //2
fn();  //3
alert(a);  //3

/*将以上改写成局部变量*/

function fn() {
var a = 1;
a++;
alert(a);
}

fn();  //2
fn();  //2
alert(a);  //出错

//以上结果是因为被垃圾回收机制回收了

/*a为局部变量,a又可以累加,采用闭包的方法*/

function fn1(){
var a = 1;
function fn2() {
a++;
alert(a);
}
return fn2;
}
var c = fn1();
c();  //2
c();  //3
alert(a);  //出错,因为是局部变量

//以上改写成如下:
function fn1(){
var a = 1;
return function(){
a++;
alert(a);
}
}

var c = fn1();
c();  //2
c();  //3
alert(a)  //出错,因为是局部变量

/*
函数声明:
  function fn(){
alert(1);
}
函数调用:
fn();

将“函数声明”改写成“函数表达式”:前面加上括号,括号内部为函数,需要调用直接后面加上括号,如下:
   (function (){
alert(1);
})();
*/

//改写代码
var c = (function(){
var a = 1;
return function(){
a++;
alert(a);
}
})();
c();  //2
c();  //3

//以上的情况,模块化代码,减少全局变量的污染


//私有成员的存在
var test = (function(){
var a = 1;
function fn1(){
a++;
alert(a);
}
function fn2(){
a++;
alert(a);
}
return {
b:fn1,
c:fn2
}
})();

test.b();  //2
test.c();  //3
alert(a);  //出错
alert(fn1());  //出错
alert(fn2());    //出错

//变量a、函数fn1和fn2为私有,以上为模块化代码的模式


  用法:

    模块化代码

    在循环中直接找到对应元素的索引

3、闭包需要注意的地方

  IE下会引发内存泄漏

  (当页面跳转时,变量不会释放,一直存在内存当中,使CPU一直在累加,只有当浏览器关闭时才释放内存)

  满足条件,如下例:一个变量(oDiv)获取DOM节点或数组对象的时候,它的一个属性(onclick)引用一个内部函数,而内部函数中这个变量(oDiv)又去引用外部的变量(oDiv),会产生内存泄漏

  

window.onload = function(){
var oDiv = document.getElementById('div');
oDiv.onclick = function(){
alert(oDiv.id);
}

  //解决内存泄漏问题
  window.onunload = function(){
oDiv.onclick = null;
}
}

方法二:
window.onload = function(){
var oDiv = document.getElementById('div');
 var id = oDiv.id;
 oDiv.onclick = function(){
alert(id);
}
oDiv = null;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: