闭包作用:
1.闭包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
2.使用闭包之后,外部函数的变量会始终存在与内存中,不会在外部函数调用后被GC回收
闭包的简单实现:
js中如果没有用var或者let声明一个函数或者变量那么这个变量会被默认认为是全局的变量
function f1(){
var n = 999;
nAdd = function(){
n += 1;
}
function f2(){
console.log(n);
}
return f2;
}
var result = f1();
result(); //从函数外部通过闭包f2获取到函数f1内部局部变量的值
nAdd(); //从函数外部通过闭包修改局部变量n的值
result(); //再次通过闭包f2获取到函数f1内部局部变量的值
这里nAdd没有用var声明,但是被赋值了一个function,此时的nAdd就可以在全局进行调用,函数就是赋值的函数
这段代码中另一个值得注意的地方,就是‘nAdd=function(){n+=1}’这一行,首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。
(为什么要使用匿名函数自执行函数,好处是什么
定义变量是需要加上var 否则会默认添加到全局对象的属性上,或者别的函数可能误用这些变量;或者造成全局对象过于庞大,影响访问速度(因为变量的取值是需要从原型链上遍历的), 实际中有的函数只调用一次使用自执行函数也是很好的。我们创建了一个匿名的函数,并立即执行它,由于外部无法引用它内部的变量,因此在执行完后很快就会被释放,关键是这种机制不会污染全局对象。)
1>由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法时,在退出函数之前,将不使用的局部变量全部删除。
2>闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法,把内部变量当作它的私有属性,这时一定要小心,不要随便改变父函数内部变量的值。