JavaScript 如何避免内存泄漏
如果你平时用手机久了,会发现后台悄悄“躺”着好多不用的App,占着电又拖慢速度——这其实和JavaScript里的“内存泄漏”是一个道理:本该被清理的“闲置数据”没被及时清掉,占了越来越多的空间,最后让程序变卡甚至崩溃。要搞定这个问题,得从日常写代码的习惯入手,避开几个容易踩的坑。
别让全局变量“占着茅坑不拉屎”
很多新手写代码图方便,喜欢直接在最外层写var a = 123这种全局变量,或者不用let/const,不小心写出全局变量——这些变量会一直存在内存里,除非页面关闭,不然永远不会被清理。举个生活化的例子:你家玄关本来是放换鞋的鞋,结果总有人把不用的快递盒、旧玩具随手放这,时间久了玄关就堆得走不动路。

改起来也简单:不用全局变量,优先用let/const声明变量,比如要临时存个数值,就写let temp = 99,用完可以手动设成null释放;如果确实需要全局存数据,用完后手动清空就行,像把玄关没用的东西及时收走或者扔掉。
别给定时器/事件监听留“尾巴”
定时器(比如setInterval)和事件监听(比如click、scroll)是最容易藏内存泄漏的地方,很多人写了就不管了,结果这些“任务”一直占着内存。比如你做了个滚动监听,页面关闭后没把这个监听删掉,它就会一直留在内存里,像你开了个电视,看完没关电源,一直耗着电。
举个具体场景:你写了个页面滚动时自动刷新的效果,代码是window.addEventListener('scroll', handleScroll),当页面切换或者关闭时,一定要记得写window.removeEventListener('scroll', handleScroll),把这个监听删掉;还有定时器,比如你设了setInterval(updateTime, 1000),不用的时候要clearInterval,不然它会一直跑,占着内存不说,还可能出错。
别让“无用引用”占着内存
JavaScript里,只要有一个地方还引用着某个数据,垃圾回收机制就不会把它清掉。很多时候你没注意,代码里藏着这种“无用引用”。比如你做了个购物车页面,把商品信息存在数组里,然后你删了某个商品,但数组里还留着这个商品的引用,或者另一个函数里还在调用它——就像你把桌上的旧杯子收进柜子,但手机备忘录里还记着“杯子在桌上”,相当于这个杯子还被“惦记”着,没法真的扔掉。
还有一种常见情况是闭包导致的内存泄漏:如果你写了个嵌套函数,外层函数的变量被内层函数引用,而内层函数又被外部调用,那外层变量就会一直存在。比如:
`javascript
function outer() {
const bigData = new Array(1000000).fill('*'); // 占内存的大数组
return function inner() {
console.log(bigData.length);
};
}
const showData = outer();
`
这里bigData本来用完就该清,但因为inner引用了它,showData又一直存在,所以bigData永远占着内存。解决方法是不用的时候手动把引用设为null,比如showData = null,这样bigData就会被回收了。
日常检测的小技巧
平时写代码可以用浏览器的开发者工具(按F12就能打开),选“Memory”标签,录一下页面运行的内存快照,看看有没有异常增长的对象。如果发现某个数据的数量一直在涨,那大概率就是内存泄漏了。
其实JavaScript的垃圾回收机制会自动清理大部分不用的内存,只要避开上面几个常见的坑,就能轻松避免内存泄漏,让你的代码运行得更顺畅。