惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
DataBreaches.Net
有赞技术团队
有赞技术团队
Jina AI
Jina AI
H
Help Net Security
D
Docker
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Blog — PlanetScale
Blog — PlanetScale
Hugging Face - Blog
Hugging Face - Blog
罗磊的独立博客
MyScale Blog
MyScale Blog
N
Netflix TechBlog - Medium
B
Blog RSS Feed
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
T
The Blog of Author Tim Ferriss
U
Unit 42
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
MongoDB | Blog
MongoDB | Blog
美团技术团队
M
MIT News - Artificial intelligence
阮一峰的网络日志
阮一峰的网络日志
博客园 - 司徒正美
Microsoft Security Blog
Microsoft Security Blog
IT之家
IT之家

博客园 - lzhdim

25个每个开发人员都应该掌握的JavaScript 数组方法 20260831 - 个人小作品更新 C#使用SQLite数据库例子 - 开源研究系列文章 20260830 - 个人小作品更新 20260829 - 个人小作品更新 13、JavaScript事件循环机制 - JavaScript学习系列文章 首款媲美分体水冷的一体水冷!微星CORELIQUID E15 360水冷散热器评测:目前为止 锐龙9 9950X3D最强性能释放 C#开发的颜色取色器 - 开源研究系列文章 - 个人小作品 成长环境 - 我的闪存 提高 SQL 语句执行速度的方法 JavaScript安全最佳实践 关闭iPhone一些默认设置,让iPhone更流畅 20260814 - 个人小作品更新 JavaScript对象与元编程 20260812 - 个人小作品更新 JavaScript 模块化系统 Markdown 语法完全指南 C# 通过 Windows API 实现进程内存读写操作 JavaScript 函数进阶课题 C#开发的基于钩子技术监测键鼠事件的例子 - 开源项目研究文章 JavaScript异步编程的演进 近十年最帅风冷!酷冷至尊V8 ACE 3DHP散热器评测:单塔能干翻双塔 20260723 - 个人小作品更新 C# 中读取CPU、硬盘和内存温度 雷柏VT3s MAX鼠标评测:中小手型用户也没有被遗忘 顶尖性能的小号电竞鼠标来了 JavaScript 中的原型与继承 1分钟查清局域网所有IP 20260714 - 个人小作品更新 WorkBuddy 完整教程手册 专为AI而生的企业级QLC SSD!长江存储PE501 61.44TB评测:超过1PB的写入测试
JavaScript常见的内存泄露问题 - JavaScript学习系列文章
lzhdim · 2026-08-23 · via 博客园 - lzhdim

多前端同学可能觉得这是浏览器或引擎该操心的事, 但理解内存管理能帮你写出更高效的代码, 还能避免各种内存泄漏的坑. 

一、常见的内存泄露场景

1) 意外的全局变量: 

function leaky() {  leak = '这是一个全局变量';  
  this.anotherLeak = '这也是全局的';  }
// 解决方法:使用严格模式 "use strict"

2) 被遗忘的定时器和回调: 

// 定时器泄漏let someData = getHugeData();
setInterval(() => {  let node = document.getElementById('node');  if(node) {    node.innerHTML = JSON.stringify(someData);  }}, 1000);
// 即使移除 DOM 节点,定时器还在引用 someData 和 node
// 事件监听泄漏function setup() {  let btn = document.getElementById('myButton');  btn.addEventListener('click', onClick);}
function onClick() {  console.log('clicked!');}
// 如果 btn 被移除但没解绑事件,相关内存无法释放

3) 闭包的不当使用: 

function outer() {  let bigArray = new Array(1000000).fill('*');
  return function inner() {    console.log('inner');    // 即使不用 bigArray,它也会被保留,因为闭包保留了整个作用域链  };}
let hold = outer();  

4) DOM引用未清理: 

let elements = {  buttondocument.getElementById('myButton'),  divdocument.getElementById('myDiv')};
function removeDiv() {  document.body.removeChild(elements.div);  // 虽然从 DOM 移除了,但 elements.div 仍引用着这个节点}

二、内存优化技巧

1) 合理使用变量作用域: 

// 不好的做法function process(data) {  let result = [];
  // 大数组处理...  for(let i = 0; i < data.length; i++) {    result.push(data[i] * 2);  }
  // 后续只使用 result 的前10项  return result.slice(010);  // 但整个 result 数组会保留在内存中}
// 更好的做法function processBetter(data) {  let result = [];
  for(let i = 0; i < 10; i++) {      if(i < data.length) {      result.push(data[i] * 2);    }  }
  return result;  // 内存占用更小}

2) 及时清理引用: 

// 定时器let timer = setInterval(() => {...}, 1000);// 不需要时clearInterval(timer);
// 事件监听function cleanUp() {  btn.removeEventListener('click', onClick);}
// WeakMap/WeakSet 允许对象被垃圾回收let weakMap = new WeakMap();let obj = {};weakMap.set(obj, 'some value');  

3) 分块处理大数据:

// 处理大数组时不要一次性处理function processLargeArray(array, chunkSize, callback) {  let index = 0;
  function next() {    let chunk = array.slice(index, index + chunkSize);    index += chunkSize;
    if(chunk.length) {      callback(chunk, next);    }  }
  next();}
// 使用processLargeArray(hugeArray, 1000(chunk, next) => {  // 处理当前块  processChunk(chunk);
  // 使用 setTimeout 或 requestIdleCallback 给浏览器喘息机会  setTimeout(next, 0);});

4) 使用对象池: 频繁创建销毁对象? 试试对象池: 

class ObjectPool {  constructor(createFn) {    this.createFn = createFn;    this.pool = [];  }
  get() {    return this.pool.length ? this.pool.pop() : this.createFn();  }
  release(obj) {    // 重置对象状态(如果需要)    this.pool.push(obj);  }}
// 使用let particlePool = new ObjectPool(() => ({  x: 0, y: 0, vx: 0, vy: 0}));
// 需要时let particle = particlePool.get();// 使用完后particlePool.release(particle);