js闭包引用以及垃圾回收探索

闭包是js的一个很大的特点,最近在网站上看到一段代码,引起了对js闭包的探讨。

var result=[];
function foo(){
    var i= 0;
    for (;i<3;i=i+1){
        result[i]=function(){
            alert(i);
        }
   }
};
foo();

针对如上代码,最终输出内容为3,即闭包中所记录的自由变量,只是对这个变量的一个引用,而非变量的值,当这个值被改变了,闭包里获得到的变量值,也会被改变。
解决办法为让内部函数在循环创建时立即执行,并且捕捉当前的索引值,然后记录在自己的一个本地变量里,然后利用返回函数的方法,重写内部函数,让下一次调用的时候,返回本地变量的值,修改后的代码如下:

var result=[];
function foo(){
    var i= 0;
    for (;i<3;i=i+1){
        result[i]=(function(j){
            return function(){
                alert(j);
            };
        })(i);
        }
};

上述代码让我想起了angularJS之中的典型闭包场景,代码如下:

function($scope, $ele, $attrs){
        var attrs = $attrs;
        debugger;
        if(undefined === $attrs.event){
            $ele.bind("click", function(){
                debugger;
                $scope.name = "123"; //1
                $ele; //2
            })
        }
    }

如上代码只是angularJS中指令的一部分,与普通的js函数没什么区别,倘若没有1和2处的代码,通过debugger方式调试时,查询 scope ele全部为异常,说明这两个变量都被回收了。但是当放开1处的代码,仅注释2处的代码,在执行过程中通过断点调试就会发现 scope ele没有内容,说明 ele scope的定义,而$scope却有值。由此便可以引申出javascript中关于闭包的两个特点,作用域链和垃圾回收机制。

首先看一下垃圾回收,当我们把1和2处的代码都注释了的时候,当执行了内部函数时,由于内部函数当前不依赖我们注释掉的那两个变量,所以这些变量就被垃圾回收器回收了,因而当我们在debugger模式下查看时就会抛出异常。而当我们只注释代码2的时候,在断点处查看 scope ele时就会有异常,由于内部没有使用 ele scope则没有被回收。

接下来看一下作用域链,在没有注释代码的情况下,当我们触发bind事件时,为什么当前函数没有定义 scope ele,却可以取到值,原因很简单,当当前作用域下没有这个变量值的时候,就会顺着函数向他的上级作用域查看,而上级作用域就是父级函数,层层向上,直至最外层。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值