在js的一个函数内部再执行事件函数绑定语句,事件函数内引用此函数的局部变量,为何外部函数运行后局部变量不会销毁?-问答-阿里云开发者社区-阿里云

开发者社区> 问答> 正文

在js的一个函数内部再执行事件函数绑定语句,事件函数内引用此函数的局部变量,为何外部函数运行后局部变量不会销毁?

2016-05-27 11:09:18 2641 1

代码:

$button1=$("#button1");
$button2=$("#button2");

function Panel(){}

Panel.prototype.activate=function(){
      var a=1;
      $button2.click(function(){
       a+=1;
       });
}

$button1.click(function(){
       new Panel().activate();
});

如题我在Panel.prototype.activate内为button2的单击事件绑定了函数,该函数内部引用了Panel.prototype.activate的局部变量a,然后我为button1元素的单击事件绑定Panel.prototype.activate函数。
之后进行操作:
1 单击button1:执行 Panel.prototype.activate函数,且botton2的单击事件被绑定函数
2 单击button2:操作Panel.prototype.activate的局部变量a

为什么局部变量a会一直存在?按道理步骤1, Panel.prototype.activate函数执行后a即被销毁?

请问这种情况这与js的闭包是一个概念吗?
我是一个新手,关于闭包,对其理解是:内部函数的执行体若引用外部函数的局部变量,并且return此变量,那么执行内部函数后,此局部变量不会被销毁。
但是问题中这种情况如何解释?

取消 提交回答
全部回答(1)
  • 小旋风柴进
    2019-07-17 19:17:25

    闭包是关于变量作用域链的
    闭包建立在函数声明阶段,而非执行阶段
    闭包是依附在函数对象上的
    JS垃圾回收是基于引用计数的
    函数执行时生成的局部变量在函数执行完毕后就会从执行栈中清除掉,但不意味着者可以GC掉,还要看其是否被引用
    那么我们回到问题
    `
    $button1=$("#button1");
    $button2=$("#button2");`
    声明了$button1变量和$button2变量

    function Panel(){}
    Panel.prototype.activate=function(){
          var a=1;
          $button2.click(function(){
           a+=1;
           });
    }

    定义了Panel函数,声明了一个匿名函数A,在匿名函数内部声明了一个内部变量a,引用了变量$button2,并在内部同事声明了一个匿名函数A1,将会使用到其定义时所处的函数的内部变量a;
    至此就会形成2个闭包,
    [闭包1]一个针对Panel函数原型对象的activate方法(函数)的闭包-可以能访问非内部变量$button2;
    [闭包2] 一个针对匿名函数的闭包-可以/需要访问activate函数的内部变量a

    $button1.click(function(){
           new Panel().activate();
    });

    声明了一个匿名函数B,其需要访问Panel构造函数,所以匿名函数还有又构成一个闭包[闭包3]-可以/需要范围访问Panel构造函数

    在函数声明阶段完成,也就是词法作用域分析结束后
    开始代码的执行,
    为Panel函数原型添加了一个方法activate并将其指向声明的匿名函数A
    为$button1绑定click事件回调匿名函数B

    当$button1触发click事件后,匿名函数B被执行,利用闭包能够访问到Panel函数,进而新建了一个Panel对象,并执行了activate方法,初始化变量a,用到闭包能够访问到$button2,为$button2绑定click事件回调匿名函数A1.
    当$button2触发click事件,匿名函数A1就被访问,利用前面的闭包能够访问a
    匿名函数A1/匿名函数B分别绑定在$button2,$button1上的,这个2个对象都函数都还有引用,所以执行完了以后函数对象不会被GC掉,那么闭包也就保留着,闭包保留着,那么对其中的变量就会有引用存在,那么变量就不会被清除的

    闭包中的变量并不会随着函数的执行完毕而被清除掉,反而会一直保留着,除非这个闭包被清除-也就是闭包中涉及的变量再也没有被别的函数引用到。
    例如

    function add10(init){
        var a=10;
        var add=function(){
            a+=10;
        }
        add();
        return a;
    }
    console.log(add10(10));//输出20

    add函数就会形成一个闭包,可以/需要访问变量a
    但在add10函数执行完了后,闭包将会消失,因为没有其它对象会引用到函数add,那么可以GC掉add,闭包也就失去了其依赖的对象,也就会被GC掉

    0 0
相关问答

12

回答

在阿里云上安装和运行Node.js全功略

ycwong 2013-09-18 15:17:30 66922浏览量 回答数 12

19

回答

【分享】如何提高网站的打开速度?

enj0y 2012-11-17 14:35:22 58022浏览量 回答数 19

145

回答

【新手入门】云服务器linux使用手册

fanyue88888 2012-11-26 17:14:18 160021浏览量 回答数 145

28

回答

钉钉开放平台“常见问题常见问题常见问题“重要请关注

竹梅 2015-12-03 00:39:14 96664浏览量 回答数 28

22

回答

爬虫数据管理【问答合集】

我是管理员 2018-08-10 16:37:41 148980浏览量 回答数 22

31

回答

[@倚贤][¥20]刚学完html/css/js的新手学习servlet、jsp需要注意哪些问题?

弗洛伊德6 2018-10-27 21:52:43 148089浏览量 回答数 31

23

回答

【云服务器分享】网站访问速度快才是硬道理

dreamdoo 2012-10-15 10:15:02 86578浏览量 回答数 23

13

回答

【云服务器分享】如何节省网站流量

dreamdoo 2012-10-15 10:36:09 81813浏览量 回答数 13

15

回答

对象存储oss【问答合集】

我是管理员 2018-08-03 14:54:02 69633浏览量 回答数 15

3

回答

Nginx—owncloud安装记事

寒喵 2014-06-07 23:24:41 49755浏览量 回答数 3
2710
文章
6591
问答
问答排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载