zoukankan      html  css  js  c++  java
  • javascript闭包

    前言


      我们知道,变量根据作用域的不同分为两种:全局变量和局部变量。

    • 函数内部可以访问全局变量和局部变量
    • 函数外部能访问全局变量,不能访问局部变量
    • 当函数执行完毕,本作用域的局部变量销毁。  

      如:

    function foo() {
      let a = 1;
    }
    foo();
    console.log(a);  
    //打印报错:Uncaught ReferenceError: a is not defined

      上面代码中,由于变量a是函数内的局部变量,所以外部无法访问。

      但是,在有些场景下,我们就是想要在函数外部访问函数内的局部变量的时候,就需要引入闭包的概念。

    闭包的概念和代码举例


       闭包的概念:闭包指有权访问另一个函数作用域中变量的函数。

      简单理解就是,如果这个作用域可以访问另外一个函数内部的局部变量,那就产生了闭包 (此时,我们可以把闭包理解为一种现象),而另外那个作用域所在的函数称为闭包函数。

      闭包代码举例

    function fn1() {
      let a = 10;
      
      function fn2() {
        console.log(a);
      }
      fn2();
    }
    fn1();

      打印结果:10

      上面代码中,函数fn2的作用域访问了fn1中的局部变量,那么此时在fn1中就产生了闭包,fn1称为闭包函数。

    闭包的创建


       闭包就是可以创建一个独立的环境,每个闭包里面的环境都是独立的,互补干扰。闭包会发生内存泄漏,每次外部函数执行的时候,外部函数的引用地址不同,都会重新创建一个新的地址。但凡是当前活动对象中有被内部子集引用的数据,那么这个时候,这个数据不删除,保留一根指针给内部活动对象。

      闭包内存泄漏为:

       一块被分配的内存既不能使用,也不能回收。作为一般的用户,根本感觉不到内存泄漏的存在。真正有危害的是内存泄漏的堆积,这最终会消耗尽系统所有的内存,从而影响性能,甚至导致程序崩溃。

      内存泄漏的解决办法:

       常用的解决方法就是在JavaScript代码段运行完的时候将形成循环引用的JavaScript对象手动设置为空,切断引用。

    function fn1() {
      let a = 10;
      
      return function() {
        console.log(a);
      }
      a = null; //添加的语句 } fn1();

    闭包的作用


    function Person(){ 

      var name = "default";

      return {
        getName : function(){
          return name;
        },
        setName : function(newName){
          name = newName;
        }
      }
    };

    var john = Person();
    print(john.getName());  //default
    john.setName("john");
    print(john.getName());  //john

      总结:

      1️⃣ 闭包可以从外部读取函数内部的变量,也就是延伸了变量的作用范围,避免了使用全局变量,防止全局变量污染;

      2️⃣ 将创建的变量的值始终保持在内存中;(代码中,name一直保存在内存中,并没有在对象中的两个函数调用后被清除)

      3️⃣ 闭包可以使不同的对象拥有独立的成员及状态,互不干涉;(setName和getName都是Person这个类的实例,两个实例对name这个成员的访问是独立的互不影响的)

  • 相关阅读:
    Sublime Text 3 Build 3143 可用License
    npm安装cnpm报错
    使用proxy来简单的实现一个观察者
    时间倒计时提醒
    JavaScript设计模式
    异步方法(promise版)出错自调用
    co模块源码学习笔记
    go new() 和 make() 的区别
    广度优先搜索算法
    并发和并行有什么区别?(转)
  • 原文地址:https://www.cnblogs.com/wannacc-xx/p/13798616.html
Copyright © 2011-2022 走看看