javascript 作用域闭包

什么是闭包

  当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。我们先看一段代码

function foo() { 
  var a = 2; 

  function bar() {
   console.log( a ); // 2 
  }

  bar(); 
}

foo();

  上面这个是闭包吗?很遗憾,从定义的角度来说它并不是。

function foo() { 
  var a = 2; 

  function bar() { 
    console.log( a );
  }

  return bar;
 }

var baz = foo(); 

baz(); // 2 ———— 朋友,这就是闭包的效果。

  我们用全局变量baz接收了 foo返回的函数 bar,因此我们阔以在其他任何作用域中使用 baz去获取 foo内部的元素。这种就是闭包。

var fn; 

function foo() { 
  var a = 2;

 function baz() { 
    console.log( a ); 
  }

  fn = baz; // 将baz分配给全局变量
}

function bar() { 
    fn(); // 妈妈快看呀,这就是闭包! 
}

foo(); 

bar(); // 2

  无论通过何种手段将内部函数传递到所在的词法作用域以外,它都会持有对原始定义作用域的引用,无论在何处执行这个函数都会使用闭包。
  如果你很熟悉jQuery(或者其他能说明这个问题的JavaScript框架),可以思考下面的代码:

 function setupBot(name, selector) { 

    $( selector ).click( function activator() { 
      console.log( "Activating:" + name ); 
    } );

 }

setupBot( "Closure Bot 1", "#bot_1" ); 
setupBot( "Closure Bot 2", "#bot_2" );

  本质上无论何时何地,如果将函数(访问它们各自的词法作用域)当作第一级的值类型并到处传递,你就会看到闭包在这些函数中的应用。在定时器、事件监听器、Ajax请求、跨窗口通 信、Web Workers或者任何其他的异步(或者同步)任务中,只要使用了回调函数,实际上就是在使用闭包!

闭包的特点

  1. 让外部访问函数内部变量成为可能;
  2. 局部变量会常驻在内存中;
  3. 可以避免使用全局变量,防止全局变量污染;
  4. 会造成内存泄漏(有一块内存空间被长期占用,而不被释放)
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。