今天遇到一个很有争议的问题,在这里分享一下,我相信对于即将面试前端的小伙伴会有帮助的。

主要内容是围绕下边的问题展开的,文章涉及到的其他方面的知识点不展开叙述。

问题:闭包会不会造成内存泄漏?

什么是内存泄漏

不再用到的内存,没有及时释放,就叫做内存泄漏。在 js 中,详细一点说就是指我们已经无法再通过js代码来引用到某个对象,但垃圾回收器却认为这个对象还在被引用,因此在回收的时候不会释放它。导致了分配的这块内存永远也无法被释放出来。如果这样的情况越来越多,会导致内存不够用而系统崩溃。

垃圾回收机制

js 引擎为了解决内存泄漏问题,才有了垃圾回收机制,能够让 js 自动的管理内存,将内存中不在使用的变量回收掉,然后释放出内存空间。

js 用了两种策略,一个是标记清除法,另一种是引用计数法,其实他两的实现原理我们只明白一点就是都是通过判断当前的变量是否被引用,如果没有被引用,就说明该变量应该被回收,怎么回收就是上边说得两种策略的事情了。

什么是引用?

再多说一句,什么是引用?所谓的引用就是存储在堆内存中的对象你是直接不能访问的,而是通过栈内存中存储该对象的地址访问的,改地址就保持着对该对象的引用。

就好比一个盒子,盒子里有一块糖,糖和盒子外部有一根绳子连接着,如果你想直接打开盒子取出糖,不好意思,盒子被上锁了,如果你通过绳子将糖从盒子的小孔中取出来是可以的,就相当于我们所说的引用,糖就是所谓的对象,盒子相当于堆内存。

闭包真的会产生内存泄漏??

对闭包有了解的小伙伴知道,闭包的作用就是就是可以在在一个函数的内部可以访问到函数外部的变量。这是因为内部函数对外部函数属于同一作用域内,通过闭包内的函数访问到变量是因为内部函数保持着对变量的引用,当注册一个点击事件的时候,就是一个闭包,当点击事件完成的时候,还会对改变量保持着引用。

这时候网上有很多的歧义,说闭包造成了内存的泄漏,还有很多面试官问闭包造成的内存泄漏,最后通过大量的资料我终于查明白了,虽然很多大量的博客说遇到了闭包泄漏的实际问题,大部分都将原因归结为闭包产生了内存泄漏。其实内存泄漏并不是闭包造成的,而是通过闭包内的函数对变量的引用,闭包不是真正产生内存泄漏的原因!

大量博客记录的实际遇到的闭包产生内存泄漏问题的根本原因就是没有及时的断开对变量的引用,而不是注册监听事件的闭包产生的内存泄漏。如果我们对该引用可以进行控制,就可以解决内存泄漏的问题,而不应该把这个锅甩给无辜的闭包。

如果你在面试中,面试官说到闭包会产生内存泄漏问题,你就可以放弃这家公司了,因为面试官根本也不懂闭包之所以产生内存泄漏的真正原因。