• JS:闭包


    一、变量的作用域

    要理解js的闭包,首先要了解js的变量作用域;

    (1)js的变量有两种:全局变量,局部变量;

    js的局部变量只会在函数内部通过var声明产生,不是通过var声明的变量也会被当成局部变量

        var a = 'a';
        function myFunc() {
          var b = 'b';
          c = 'c';
        }
        myFunc();
        console.log(a); // output: a
        console.log(c); // output: c
        console.log(b); // output: Uncaught ReferenceError: b is not defined

    上面结果:a, c都能在全局访问,都是全局变量, b不能再全局访问,所以是局部变量。c虽然定义在内部,但是由于没有通过var时声明,所以是全局变量。

    (2)变量的作用域

    看下面的例子:

        var a = 'a';
        function myFunc() {
          var b = 'b';
          console.log('inner func:', a); // a
          console.log('inner func:', b); // b
        }
        myFunc();
        console.log(a); // output: a
        console.log(b); // output: Uncaught ReferenceError: b is not defined

    从上面的例子可以看出,函数内部可以读取函数外部的变量,而函数外部不可以读取函数内部的变量。

    二、闭包

    某些情况下,需要在函数外部访问函数内部的变量,正常情况是办不到的。但是我们可以想个办法:在函数内部再定义一个函数,然后再把该函数作为返回值返回,我们就可以实现在函数的外部,读取函数内部的变量了。而作为返回值的这个函数就是闭包。

    function f1() {
    
       var n = 999;
        function f2() {
          console.log(++n)
          }
       return f2;
     }
    f2就是闭包,可以让外部访问内部函数的变量n。
    有些人会有疑问,在f1中直接返回n不也可以让外部访问内部函数的变量了吗?就像下面这样:
        function f1() {
          var n = 999;
          return ++n;
        }
        var result1 = f1(); // 1000
        var result2 = f1(); // 1000
    上面虽然能访问变量,但是n在函数执行完之后就被销毁了,没有被保存下来。但是用下面的这个方法,虽然外部函数在执行完之后被销毁了, 但是n就被保存下来了:
    function f1() {
    
      var n = 999;
      function f2() {
        return ++n;
      }
      return f2;
    }
    
    var result = f1();
    result(); // 1000
    result(); // 1001
    result(); // 1002

    因此闭包有两个用处:(1)可以使函数外部读取函数内部的变量; (2)让函数内部的变量始终保存在内存中。

    因为闭包会使函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决放法是:在退出之前, 将不使用的局部变量全部删除;

  • 相关阅读:
    发现pythonWin里面的一个地方挺别扭
    细节-质量-态度
    对于Borland出售IDE业务的一点感想
    ReView100遍?!
    代码生成原则Top10
    使用asp.net进行多关键字查询的例子
    代码生成FAQ(翻译)
    msdn中文上的几篇有用的sqlServer2000的文章
    RSS 阅读工具Omea Reader
    Ubuntu18.04 安装Postgresql12
  • 原文地址:https://www.cnblogs.com/ycherry/p/10845594.html
Copyright © 2020-2023  润新知