谈谈对闭包理解

在我刚接触代码那段时间内,对于闭包的概念一直摸棱两可,对于闭包的应用也是不清楚,有的时候自己用到了也浑然不知。现在,终于对闭包有了一些小小的认识。

1.什么是闭包

我认为解释闭包应该从两个方面去入手,即javascript引擎垃圾处理机制和作用域:

我们先来看看javascript引擎垃圾处理机制,我们先来申明一个函数

function computed(){
    var a=1;
    var b=2;
    function add(){
        console.log(a+b)
        return a+b
    }
    return add
}

我们先来看看在javascript引擎垃圾处理机制:函数中声明一个变量,就将这个变量标记为“进入环境”。从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到它们。而当变量离开环境时,则将其标记为“离开环境”。

垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记。然后,它会去掉环境中的变量以及被环境中的变量引用的标记。而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后。垃圾收集器完成内存清除工作,销毁那些带标记的值,并回收他们所占用的内存空间。

简单的说当我们调用computed函数时,函数内部变量进入上下文环境,函数调用结束,这些变量将被回收。

现在我们来调用一下这个函数:

var foo=computed()

根据javascript的回收机制,调用完毕后,函数内部变量应该被回收,此时,我们调用foo()发现,控制台依旧打印了3,哇,这是什么情况。原来这就是闭包的神奇之处,它阻止了computed函数内部变量的回收,内部作用域依然存在,是谁在使用这个内部的作用域?原来是add()本身在使用,它拥有涵盖computed函数内部作用域的闭包,使得该作用域能够一直存活,以供之后引用。

了解了垃圾回收机制,我们再来看看作用域:

我们再来看一个代码:

function computed(){
    var a=1;
    var b=2;
    function add(x,y){
        a=x;
        b=y;
        console.log('a='+a,'b='+b)
        return a+b
    }
    return add
}

我们知道外部作用域是无法访问函数内部作用域的变量,所以我们无法更改函数computed内a,b的值。

这时候,我们调用一下函数:

var foo=computed()
foo(10,20)

神奇的事情发生了,控制台打印a=10,b=20,我们不仅访问了函数内部的值,还更改了他,这就是闭包的作用,通过闭包就是能够读取其他函数内部变量。

以上只是我个人对闭包的理解,错误之处,希望大大们能帮忙指正,感激不尽。

 

你可能感兴趣的:(js)