闭包

作用域

理解闭包之前我们要弄清楚js的变量作用域,变量作用域就2种,

  • 全局变量
  • 局部变量

Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。

  var a=1;
 function fn(){
   console.log(a);
 }
 fn(); //1

函数外部不能读取函数内部的局部变量

 function fn(){
   var a=1;
 }
  console.log(a);//报错

注意:函数内部声明变量的时候,一定要使用var声明。如果不用的话,实际上声明的是一个全局变量。如下

 function fn(){
   var a=1;
 }
  fn()
  console.log(a);//1

外部读取局部变量

当有时候我们需要从外部得到函数内部的变量时,这个时候我们可以在函数内部再定义一个函数

function fn1(){
  a=1;

  function fn2(){
     console.log(a); // 1
    }
 }

  • 函数fn2就被包括在函数fn1内部,这时fn1内部的所有局部变量,对fn2都是可见的。但是反过来就不行,fn2内部的局部变量,对fn1 就是不可见的。这就是Javascript语言特有的“链式作用域”结构.
  • 子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。
  • 既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们就可以在f1外部读取它的内部变量。如下
function fn1(){
  a=1;
  function fn2(){
    console.log(a);
  }
  return fn2;
}
var result=fn1();
result(); // 1

闭包的概念

  • 闭包就是指函数可以记住并访问所在的词法作用域,并且保持着对词法作用域的引用,即使函数在当前作用域之外执行,就会形成闭包。
  • 对于闭包的形成,实质上就是所涉及的词法作用域和将函数作为值return
  • 当在函数内部声明了内部函数,并将内部函数作为值返回,就会产生闭包。
  • 在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

例子

这样在执行完var c=a()后,变量c实际上是指向了函数b,再执行c()后就会弹出一个窗口显示i的值(第一次为1)。这段代码其实就创建了一个闭包,为什么?因为函数a外的变量c引用了函数a内的函数b,就是说:
当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。

你可能感兴趣的:(闭包)