面试题答案
一键面试闭包的工作原理
- 概念:闭包是指有权访问另一个函数作用域中的变量的函数。在
outerFunction
内部创建并返回的innerFunction
形成闭包。 - 原理:当
outerFunction
执行时,它的执行上下文被创建,在其中声明的变量会存在于该上下文的变量环境中。当outerFunction
返回innerFunction
时,innerFunction
依然保持对outerFunction
作用域的引用。这意味着即使outerFunction
执行完毕,其执行上下文从调用栈中弹出,但由于innerFunction
的存在,outerFunction
作用域中的变量不会被垃圾回收机制回收,innerFunction
可以继续访问和操作这些变量。
匿名函数可能导致的内存泄漏陷阱
- 循环引用:如果
innerFunction
持有对外部对象(如 DOM 元素等)的引用,而该外部对象又持有对innerFunction
的引用,就会形成循环引用。在一些旧版本浏览器(如 IE 低版本)中,垃圾回收机制无法处理这种循环引用,导致相关对象无法被回收,从而造成内存泄漏。 - 长时间持有大量数据:由于闭包会保持对外部作用域变量的引用,如果外部作用域中有大量数据(如大数组、大对象等),并且
innerFunction
长时间存在(例如被全局变量引用),这些数据就无法被回收,占用过多内存。
避免这些陷阱的方法
- 打破循环引用:在适当的时候手动解除循环引用。例如,如果是 DOM 元素与闭包函数的循环引用,在移除 DOM 元素时,手动将闭包函数对 DOM 元素的引用设为
null
,同时确保 DOM 元素不再引用闭包函数。 - 减少不必要的引用:尽量避免在闭包中引用不必要的外部变量,特别是大对象或大数组。如果必须使用,可以考虑传递副本而不是直接引用,这样在闭包函数执行完毕后,原对象可以正常被垃圾回收。
- 及时释放引用:当
innerFunction
不再需要时,及时释放对它的引用,使其可以被垃圾回收机制回收,从而也能让它所引用的外部作用域变量被回收。