zoukankan      html  css  js  c++  java
  • JavaScript--闭包

    闭包的概念:

      在计算机科学中,闭包(也称词法闭包或函数闭包)是指一个函数或函数的引用,与一个引用环境绑定在一起。这个引用环境是一个存储该函数每一个非局部变量(也叫自由变量的表)。已晕^^

      闭包,不同于一般的函数,它允许一个函数在立即词法作用域外调用时,仍然访问非本地变量 ——from维基百科

      闭包其实就是能够读取其他函数内部变量的函数。

      由于在javascript语言中,只由函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”

      所以,在本质上,闭包就是将函数内部和函数外部链接起来的一座桥梁

                                                                                ——form阮一峰

      理解闭包需要先了解一下“变量作用域”和“如何读取局部变量”的概念:

    一、变量的作用域:

    变量的作用域无非就是两种:全局变量局部变量

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

    var scope = "local scope";
    function outer(){
      console.log(scope);
    }
    outer(); //local scope

    另一方面,在函数外部自然无法读取函数内的局部变量:

    function outer(){
      var scope = "local scope";
    }
    outer(); console.log(scope);

    大家想下,上述的结果会是肿么样呢?

    答案当然是大家所想的error了: scope is not defined 

    还有一个需要注意的地方,函数内部声明变量的时候,一定要使用var关键字,如果不用的话,那么你实际上是声明了一个全局变量

    function outer(){
      scope = "local scope";
    }
    outer();
    console.log(scope);

    ???这个的答案是啥呢? local scope 所以要记得使用var关键字额

    二、如何从外部读取局部变量?

    读取局部变量?刚刚不是说无法读取到函数内的局部变量me?晕了^^

    其实是酱紫的,通常情况下是无法读取到函数内部的局部变量的,不过通过变通方法就可以实现鸟!

    那就是在函数的内部定义一个函数。

    function outer(){
      var scope = "local scope";
      function inner(){
    console.log(scope);//local scope
    }
    }

    在上面的代码中,函数inner被包含在函数outer内部,这时outer内部的所有变量,对inner都是可见的。但是反过来就不行了,inner内部的局部变量,对outer是不可见的。这就是javascript语言特有的“链式作用域”结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。

    既能inner可以读取outer中的局部变量,那么只要把inner作为返回值,我们就可以在outer外部读取它的内部变量了吗!

    function outer(){
      var scope = "local scope";
      function inner(){
        console.log(scope)
      }
      return inner;
    }
    var func = outer();
    func();

    这次的结果会是 scope is not defined 吗?

    大家去验证下吧。

    其实答案是这样子的 local scope

    上述代码中inner函数,就是闭包

    闭包的用途

    闭包可以用在很多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的局部变量,另一个就是让这些变量始终保持在内存中。

    function outer(){
      var n = 999;
      nAdd = function(){n+=1};
      function inner(){
        alert(n);  
      }
      return inner;
    }
    var result = outer();
    result();  //999
    nAdd();
    result();  //1000

    在这段代码中,result实际上就是闭包inner函数,它一共运行了两次,第一次的值是999,第二次的值是1000,这证明了,函数outer中的局部变量n一直保存在内存中,并没有在inner调用后自动清除。

    使用闭包的注意点

    闭包灵活和方便,

    闭包也存在“空间浪费”,“内存泄漏”,“性能消耗”的问题,所以不能滥用闭包。

    原文地址

  • 相关阅读:
    Creating a Simple Direct2D Application
    关于ssh加密方式的理解
    关于2147217913 从 char 数据类型到 datetime 数据类型的转换导致 datetime 值越界 的问题解决方法
    关于 win2003中ASP.Net 的edit configuration 无法使用的答疑
    vc 用ado访问Oracle数据库的代码示例
    手工移除vs6的VSS绑定
    关于:无法执行值从 char 到 char 的隐性转换,因为该值的排序规则因排序规则冲突而未能解决
    vs2003 无法进行调试的经历
    关于如何在VMware上安装Puppy Linux
    VB: DataGrid 的列可见问题
  • 原文地址:https://www.cnblogs.com/White-Quality/p/5252582.html
Copyright © 2011-2022 走看看