js闭包,阮老师说:‘闭包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。’ 这里可能要先去理解一下全局 变量和局部变量,这里先不做过多的解释!
接下来通过几个例子,谈一下对比包的理解以及各种闭包的写法,下面的例子可能不够专业,但是对于闭包的理解个人认为还是有很大的帮助的!
<b>例子1:</b>
function a(){
var b = 1;
return function c(){
console.log(b)
}
}
a()(); //1
这个函数调用时,a()(),有两个括号,第一个是调用a函数,第二个是执行c函数。 如果单独执行a();返回的就是c函数的函数体,这里就是把c函数,缓存了一下,并没有立即执行!
<b>例子2:</b>
function a(){
return function(){
console.log(0)
}
}
a()(); //0
这种写法,和上面一种写法差不多,但是缓存的时候是匿名函数,但是调用的方法是相同的!
<b>例子3:</b>
function a() {
var b = 1;
function c() {
alert(b);
}
return c;
}
var d = a();
d(); // 1
分析一下例子3,应该可以看出c函数是一个闭包的形式,一个函数里面嵌套了另外一个函数,被嵌套的函数被缓存了,也就是c函数,但是此处的写法略有不同,var d = a(); d();等同于a()();这里只是进行了一次缓存,这样就好理解了;
还有要注意的是:这段代码有两个特点:
1、函数c嵌套在函数a内部;
2、函数a返回函数c。
<b>例子4:</b>
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function() {
return function() {
return this.name;
};
}
};
alert(object.getNameFunc()()); //The Window
解释一下,其实这块很简单,getNameFunc()第一次执行时,如果在里面打印出this的话,这个this指向的是object,就返回了function() {return this.name;};,当getNameFunc()()执行时,就是执行function() {return this.name};这样一句话,这里的this指向的就是window了,所以最后的结果就是The Window了;
<b>例子5:</b>
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};
alert(object.getNameFunc()()); //My Object
这个例子的话,和上面的相比,多了var that = this;
,然后返回的是that.name;
;参考上面的解释,很明显可以看出,因为var that = this, 返回的that.name,改变了this的指向,that指向的就是object了,所以最后的结果就是My Object了;
使用闭包的注意点:
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
如果理解这些,我觉着闭包也就八九不离十了!