一、闭包的定义
闭包就是能够读取其他函数内部变量的函数。在js中,可以将闭包理解成“函数中的函数“。
二、闭包的形成
1、子函数内使用了某个祖先函数内声明的一个变量(闭包变量,受保护的数据).
2、子函数还可以在任意时间被调用.
三、闭包的作用
1、可以读取函数内部的变量
2、让这些变量的值始终保存在内存中。这是因为闭包的执行依赖外部函数中的比那辆,只有闭包执行完,才会释放变量所占的内存
四、闭包的影响
1、闭包变量会一致存在内存之中.不会被销毁;
2、那个祖先函数被调用多少次,就会构成多少个局部变量(互不相同);
3、子函数调用时,会顺着对应的作用域链找到相应的闭包变量;
五、闭包的表现形式
5.1、闭包,因为可以通过全局fn任意时间调用子函数。
function show(){
var x=10;
return function(){
console.log(x);
}
}
var fn=show();
var oBtn=document.getElementById("btn");
5.2、闭包,因为可以任意时间调用事件句柄。
function show(){
var x=10;
oBtn.onclick=function(){
alert(x);
}
}
var abc=null;
function show(){
var x=10;
abc=function(){
console.log(x);
}
}
show();
六、什么时候用闭包?
1、设计私有的方法和变量
2、防止函数在被调用之后内部变量被销毁
七、使用闭包的注意事项
(1) 问题:由于闭包会使得函数中的变量都被保存在内存中,内存消耗大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能会造成内存泄露。
解决方法:在退出函数之前,将不使用的局部变量全部删掉
(2) 问题:闭包会在父函数外部,改变父函数内部变量的值。
如果把父函数当做对象使用,把闭包当做公用方法,把内部变量当做私有属性,此时不要随便改变父函数内部变量的值。
举例说明:
//----代码一
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
//js中,函数就是作用域
return function(){
// 闭包 + this,造成的问题,函数中的this不能访问到作用域外的变量
return this.name;
};
}
};
//this的作用域是在函数执行的时候确定,因为匿名函数是一个全局变量,因此this指向的是window对象
alert(object.getNameFunc()()); // 因此输出结果是:The Window
//-----代码二
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
//--this指向object,保留了对象object在that里面,
var that = this;
return function(){
//这里输出对象object的name属性的值
return that.name;
};
}
};
alert(object.getNameFunc()()); // 所以暑促值:My Object
八、闭包的特性
1、引用的变量不被垃圾回收机制收回
2、函数内部可以引用外部的变量;
3、函数里面嵌套函数
九、闭包中的this对象
var num = 1;
var obj = {
num:2,
getNum:function() {
return function () {
return this.num;
}
}
}
alert(obj.getNum()()); //num -> 1
为什么不弹出2呢,这里是说明闭包中你需要注意现在的this的指向那一个对象,其实记住一句话就永远不会用错this的指向问题,this永远指向调用它的作用域;
如果这样写你就可能理解了
var num = 1;
var obj = {
num:2,
getNum:function() {
return function () {
return this.num;
}
}
}
var a = obj.getNum();
alert(window.a()); //1
原理解释:其实是window对象调用的,这就是说闭包中的this让你看不清this的指向;
如果你想alert2的话,就应该这样写
var num = 1;
var obj = {
num:2,
getNum:function() {
var _this = this;//在这里保存this
return function () {
return _this.num;
}
}
}
var a = obj.getNum();
alert(window.a()); //2
十、闭包的使用例子,加深理解闭包
<script type="text/javascript">
//创建数组元素
var num = new Array();
for(var i=0; i<4; i++){
//num[i] = 闭包;//闭包被调用了4次,就会生成4个独立的函数
//每个函数内部有自己可以访问的个性化(差异)的信息
num[i] = f1(i);
}
function f1(n){
function f2(){
alert(n);
}
return f2;
}
num[2](); //2
num[1](); //1
num[0](); //0
num[3](); //3
</script>