• JavaScript之闭包(重新认识)


          最近又重新学习了闭包,发现之前没有深刻理解作用域链,学习作用域链后对闭包才可以做到真正的理解。

          闭包是指有权另一个函数作用域中变量的函数。要理解闭包首先理解作用域链。

          执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有与之关联的变量对象,保存了环境中定义的所有变量和函数。只有解析器在处理数据是我才可以访问这个变量。当代码在一个环境中执行时,会创建变量对象的一个作用域链,它保证了执行环境对有权访问的变量和函数的有序访问。

         当某个函数被调用时,会创建一个执行环境及相应的作用域链。作用域的最前端,始终都是当前执行代码所在环境的变量对象,下一个变量对象来自外部环境,以此类推,直到全局作用域中的变量对象作为作用域链的终点。作用域链中一定不会包含其内部子函数的变量对象,但子函数的作用域链包含函数的局部变量,因此这决定创建闭包的方法是在一个函数内部创建另一个函数,内部函数可以引用外部函数的变量。

    闭包与变量

          闭包只能取得函数中任何变量的最后一个值,如下创建一个数组函数

    function creatFunction(){
      var result = new Array();
      for (var i=0; i<10; i++){
      result[i] = function(){
              return i;
       };
    }
      return result;
    }

    表面上每个函数都会返回自己的索引,实际上都返回10。这是因为每个函数都引用作用域链中同一个变量i,当creatFunction()函数返回后,i的值是10。解决方法

    (1) 创建匿名函数封装

    function creatFunction(){
      var result = new Array();
      for (var i=0; i<10; i++){
      result[i] = function(num){
                function(){
                      return num;  
             };
       }(i)
    }
    return result;
    }

    (2)使用ES6的let

    ES6 新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。

    function creatFunction(){
      var result = new Array();
      for (let i=0; i<10; i++){
             result[i] = function(){
                 return i;
           };
      }
    return result;
    }

    闭包特性

    (1)封闭性:外界无法访问闭包内部的数据,如果在闭包内声明变量,外界是无法访问的,除非闭包主动向外界提供访问接口;

    (2)持久性:一般的函数,调用完毕之后,局部活动对象就会被销毁,内存中仅保存全局作用域。而对于闭包来说,在外部函数被调用之后,闭包结构依然保存在。

    闭包问题

    (1) 占用内存。由于闭包携带包含它函数的作用域,因此会比其他函数占用更多内存。

    (2) 引起内存泄漏。 闭包中引用HTML元素将无法被销毁。解决方法是将需要使用的DOM元素副本的属性保存在变量中,结束会销毁DOM元素。

  • 相关阅读:
    slf4j日志框架绑定机制
    Btrace使用入门
    JVM反调调用优化,导致发生大量异常时log4j2线程阻塞
    [转载]Javassist 使用指南(三)
    [转载]Javassist 使用指南(二)
    [转载]Javassist 使用指南(一)
    数组升序排序的方法Arrays.sort();的应用
    copyOfRange的应用
    copyOf数组复制方法的使用(数组扩容练习)
    binarySearch(int[] a,int fromIndex,int toIndex, int key)的用法
  • 原文地址:https://www.cnblogs.com/microcosm/p/6985790.html
Copyright © 2020-2023  润新知