js中的闭包

1.形成的条件:

  • 函数嵌套
  • 内部函数需要使用外部函数的变量或者是形参
function init() {
    var name = "Mozilla"; // name 是一个被 init 创建的局部变量
    function displayName() { // displayName() 是内部函数,一个闭包
        alert(name); // 使用了父函数中声明的变量
    }
    displayName();
}

init();

 displayName() 没有自己的局部变量。然而,由于闭包的特性,它可以访问到外部函数的变量

2.闭包的好处与坏处

  • 好处         

        保护函数内的变量安全 ,实现封装,防止变量流入其他环境发生命名冲突 

        在内存中维持一个变量,可以做缓存(但使用多了同时也是一项缺点,消耗内存)

        匿名自执行函数可以减少内存消耗

  •  坏处

         其中一点上面已经有体现了,就是被引用的私有变量不能被销毁,增大了内存消耗,造成内存泄漏,解决方法是可以在使用完变量后手动为它赋值为null

         其次由于闭包涉及跨域访问,所以会导致性能损失,我们可以通过把跨作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响

3.哪里会出现闭包

  • 返回一个函数
  • 作为函数参数传递
var a = 1;
function foo(){
    var a = 2;
    function baz(){
        console.log(a);
    }
bar(baz);
}
function bar(fn){
    // 这就是闭包
    fn();
}
    // 输出2,而不是1
foo();
  •  在定时器、事件监听、Ajax请求、跨窗口通信、Web Workers 或者任何异步中,只要使用了回调函 数,实际上就是在使用闭包。 以下的闭包保存的仅仅是window和当前作用域
    // 定时器
setTimeout(function timeHandler(){
    console.log('111');
},100)
    // 事件监听
$('#app').click(function(){
    console.log('DOM Listener');
})
  •  IIFE(立即执行函数表达式)创建闭包, 保存了 全局作用域 window 和当前函数的作用域 ,因此可以全局的变量。
var a = 2;
(function IIFE(){
    // 输出2
    console.log(a);
})();

 

你可能感兴趣的:(javascript,开发语言)