关于闭包的疑问
发布于 7 年前 作者 heqs 4094 次浏览 来自 问答
       var foo = function () {
            var x = 0;
            var bar = function () {
                x++;
                console.log("bar x:" + x);
            }
            return bar;
        }
        var fn = foo();
        for (var i = 0; i < 5; i++) {
            fn();
        }

如上面的demo,每调用fn()一次,x就增加1,意味着x并没有被gc,那么是否意味着这个x永远都不会被gc,那不就内存泄漏了,如果是这样,要怎样才能使fn()调用结束后被gc呢?

14 回复

不知道对不对哈 循环结束后 fn = null; 不对勿喷

等同于 new 了一个对象 ,把对象引用去掉就行了,同楼上。

先确定是不是,再问怎么做

上述例子,没发现哪里有内存泄漏,fn引用bar,bar引用x

当fn被回收时,x自然就会被回收

一楼说的没错哈,但是开发规范:尽量避免使用闭包~

@CoderIvan fn是在函数外部被定义的,即他的环境是global了,如果不手动删除,应该不会被GC吧

@heqs

因为你写的代码是会执行完的,执行完后,foo与x就都会回收,就不存在内存溢出的问题了

我表达能力有限,不知道你能不能理解我说的

关于闭包,你可以看看这里的关于内存释放的解释

然后配合这个ISSUE食用

@CoderIvan 如果是一个普通的对象,例如var global_arr=[1,2,3] 这样一个全局数组是会被当做缓存来使用的,因为他的环境是global,而那个闭包fn我也可以理解成这样一个全局对象吧,不也缓存了么

@heqs 感觉混进了一些奇怪的知识点

这样一个全局数组是会被当做缓存来使用的,因为他的环境是global

这是哪来的?没看明白

global -> fn -> bar -> x 应该不会自动释放,要手动释放吧

按楼主的逻辑,随便写一个全局变量都叫内存泄露。x 只占了64 bits 而已,fn()一万次也只有 64 bits 的占用,又不是 64 * 10000, 有什么好纠结的。

会,但是不要紧,因为V8对闭包有优化。

只要不是大量创建闭包都没有影响。

老铁,闭包的其中一个作用不就是让这些变量的值始终保持在内存中吗?

所以闭包用的姿势要正确呗。。。。

已经不同的两个作用域了,你再试下运行几次 foo()() 看下它的值,再对比下 fn 就知道其中的奥妙了

回到顶部