• JavaScript之闭包


     很多小伙伴估计都会面试遇到被问JavaScript的闭包是什么。

    在我们谈闭包之前,我们先来谈谈JavaScript的垃圾回收机制。

    JavaScript 具有自动垃圾收集机制,也就是说,执行环境会负责管理代码执行过程中使用的内存。而在 C 和 C++之类的语言中,开发人员的一项基本任务就是手工跟踪内存的使用情况,这是造成许多问题的一个根源。在编写 JavaScript 程序时,开发人员不用再关心内存使用问题,所需内存的分配以及无用内存的回收完全实现了自动管理。
    这种垃圾收集机制的原理其实很简单:找出那些不再继续使用的变量,然后释放其占用的内存。为此,垃圾收集器会按照固定的时间间隔(或代码执行中预定的收集时间),周期性地执行这一操作。
     
     
    我们来分析一下函数中局部变量的正常生命周期。局部变量只在函数执行的过程中存在。而在这个过程中,会为局部变量在栈(或堆)内存上分配相应的空间,以便存储它们的值。然后在函数中使用这些变量,直至函数执行结束。此时,局部变量就没有存在的必要了,因此可以释放它们的内存以供将来使用。在这种情况下,很容易判断变量是否还有存在的必要;但并非所有情况下都这么容易就能得出结论。垃圾收集器必须跟踪哪个变量有用哪个变量没用,对于不再有用的变量打上标记,以备将来收回其占用的内存。用于标识无用变量的策略可能会因实现而异,但具体到浏览器中的实现,则通常有两个策略:标记清除,引用计数。

    从以上的字面意思可以理解为:全局变量是不会被JavaScript垃圾回收机制给回收。
    而局部变量是:如果一直被引用,则不会立刻对该变量进行回收,直到给变量没有被引用后,回收机制开始对该变量进行回收处理。

    那么什么是闭包呢?
    闭包是指有权访问另一个
    函数作用域中的变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。
        function a() {
          var x = 5
          return function (y) {
            return x+y
          }
        }
        var result = a()
        console.log(result(5));  //10
    

     以上代码运行结果为10,好像没什么问题,其实这个时候a函数就发生了闭包,为什么呢?

    我们来捋一捋JavaScript对以上代码是怎么执行的。

    先声明了一个函数a,声明了一个变量result。

    然后result赋值的时候调用了a函数。

    a函数开始执行,在a函数内部创建了一个变量x,然后给这个x赋值,最后返回一个匿名函数。

    匿名函数就赋值给了result。

    最后打印的时候调用了这个匿名函数,并且给这个函数传了参数。

    然后开始执行这个匿名函数,因为匿名函数引用了外部函数a里的局部变量x,所以在调用a函数的时候并没有立即释放这个x函数变量。

    所以我们得到了x+传进来的5,为10。

    代码结束。

    结束之后我们是不是发现了一个问题,函数a里的局部变量x没有被垃圾回收,而是保存了下来。

    这就是JavaScript的闭包,这个闭包是发生在a函数。

    我们可以打开浏览器的调试工具(F12)sources这一栏里设置一个断点,我们来看看到底发送了啥。

    1.定义一个result 赋值的时候调用了a 进入了 var x=5这一步

    2.给x赋值之后 开始返一个函数,返回的这个函数里引用了局部变量x。

    3.返回之后等到了一个函数 并赋值给result

    4.打印的时候,我们调用result这个函数并且传一个参数为5,然后开始执行函数,又会回到a函数里的匿名函数,开始执行return x+y

    5.输出结果 10。结束之后,我们仍然可以看到result里发现函数a的变量x还是没有被回收。

  • 相关阅读:
    为什么要用do-while(0)?
    网络字节序&大小端存储
    sql语句w3school教程
    C++编码规范
    std::deque双端队列介绍
    gdb基本操作
    gdb调试多线程
    数据库基础
    删除vector所有元素
    stl迭代器失效
  • 原文地址:https://www.cnblogs.com/kongyijilafumi/p/12644159.html
Copyright © 2020-2023  润新知