简单理解js闭包

闭包,其实就是指有权访问其他函数作用域中变量的函数。

闭包有两个作用:

(1)可以在函数的外部访问到函数内部的局部变量。

(2)闭包可以使变量一直保存在内存中,不会在函数运行完销毁。

下面一一理解一下这两点

第一点,可以在函数的外部访问到函数内部的局部变量

我们都知道js是通过作用域链来控制变量访问的权限的,只能通过向上搜索作用域链而不能向下搜索作用域链,但是我们可以通过返回一个函数,在这个函数里面再返回这个变量,这样就能访问函数里的局部变量了。

function outer(){
    var count = 1;
    function closure(){
        return count++;
    }
    return closure;
}
var test = outer();
console.log(test());

有的人可能会这样认为,如果我们要访问函数内部的变量,可以直接返回它呀,为什么一定要用闭包呢?

是的,如果我们单纯的只是想获取一次这个变量是可以直接返回,但是直接返回我们也只能得到这个值一次,当调用过一次这个函数后,这个函数的环境就被销毁了,我们再次获取这个值相当于重新重建了新的局部变量。

function outer(){
    var count = 1;
    return count++;
}
var test = outer;
console.log(test()) //1,先返回count再++;
console.log(test()) //1,两次都是得到的1;

但是闭包可以让局部变量一直保存在内存中。这就是我们要说的第二点

第二点,闭包可以使变量一直保存在内存中,不会在函数运行完销毁。

我们看看这段代码

function outer(){
    var count = 1;
    function closure(){
        count++;
        console.log(count);
    }
    return closure;
}
var test = outer();
test()  //2;
test()  //3;
test()  //4;

因为closure的作用域链中包含了outer的活动对象(即outer的作用域),closure中引用了outer作用域中的count变量,然后outer函数把closure返回,并赋值给test,相当于test现在引用了closure函数对象,如果不把test显示赋值为空,那么count就会一直存在,因为closure一直在引用outer作用域中的变量。

所以如果要回收这个因为闭包而一直存在于内存中的变量,只需将引用闭包的这个变量赋值为空就好啦。

function outer(){
    var count = 1;
    function closure(){
        count++;
        console.log(count);
    }
    return closure;
}
var test = outer();
test = null; //这样count就会被回收了。

另外提一下内存泄漏,好多人都说闭包造成了内存泄漏,但是我不这么认为,内存泄漏是指没有用到的变量依然存在于内存中,占据了不必要的空间。而闭包我们用到了变量,所以也不算严格上的内存泄漏。

 

对了,提醒大家,写代码的时候要注意以下哦,不要让用不到的变量存在于内存中,这是一个比较好的习惯。也能小小的提升网页的质量。

你可能感兴趣的:(前端)