首页 > 其他分享 >前端面试资料之大厂真题篇(四)

前端面试资料之大厂真题篇(四)

时间:2024-07-29 22:26:24浏览次数:9  
标签:function 闭包 const 真题 内存 面试 引用 document 大厂

谈谈javascript中内存泄漏的几种情况?

资料来源:rss1.cn

JavaScript中的内存泄漏指的是程序运行过程中,已不再需要的内存未能及时释放,导致内存占用不断增加。内存泄漏会导致应用程序的性能下降,甚至使程序崩溃。以下是几种常见的内存泄漏情况及其解决方法:

1. 意外的全局变量

情况描述

当在函数内忘记使用 varletconst 声明变量时,该变量会被意外地添加到全局对象上,从而导致内存泄漏。

示例代码

function myFunction() {
  myVar = "I'm a global variable"; // 应该使用 var、let 或 const 声明
}
myFunction();
console.log(window.myVar); // "I'm a global variable"
解决方法

始终使用 varletconst 来声明变量。

2. 闭包中的引用

情况描述

闭包可以捕获外部函数的变量,如果这些变量被意外地保留在内存中,就会导致内存泄漏。

示例代码

function createClosure() {
  const largeArray = new Array(1000000).fill("large array");

  return function() {
    console.log(largeArray);
  };
}

const closure = createClosure();
// 大数组仍然在内存中,因为闭包引用了它

解决方法

确保在不再需要闭包时,显式地解除对外部变量的引用。

function createClosure() {
  const largeArray = new Array(1000000).fill("large array");

  return function() {
    console.log(largeArray);
  };
}

let closure = createClosure();
// 解除对闭包的引用
closure = null;

3. DOM引用

情况描述

如果一个JavaScript对象持有对DOM元素的引用,而该元素已从DOM树中移除,可能会导致内存泄漏,因为该元素无法被垃圾回收。

示例代码

const elements = [];
function createElement() {
  const div = document.createElement('div');
  document.body.appendChild(div);
  elements.push(div);
}

createElement();
document.body.removeChild(elements[0]);
// div 仍然被 elements 数组引用,无法被垃圾回收

解决方法

在移除DOM元素时,确保解除所有对该元素的引用。

const elements = [];
function createElement() {
  const div = document.createElement('div');
  document.body.appendChild(div);
  elements.push(div);
}

createElement();
document.body.removeChild(elements[0]);
elements[0] = null; // 解除引用

4. 事件监听器未解除

情况描述

在添加事件监听器时,如果不在适当的时候解除,可能会导致内存泄漏,因为事件监听器会保留对DOM元素的引用。

示例代码

const button = document.getElementById('myButton');

function handleClick() {
  console.log('Button clicked');
}

button.addEventListener('click', handleClick);
// 假设按钮被移除但监听器未解除
document.body.removeChild(button);

解决方法

在移除DOM元素之前,先解除其事件监听器。

const button = document.getElementById('myButton');

function handleClick() {
  console.log('Button clicked');
}

button.addEventListener('click', handleClick);

// 在移除元素前解除事件监听器
button.removeEventListener('click', handleClick);
document.body.removeChild(button);

5. 定时器和回调

情况描述

定时器(如 setIntervalsetTimeout)和回调函数如果未能正确清除,可能会导致内存泄漏。

示例代码

function startTimer() {
  setInterval(() => {
    console.log('Timer running');
  }, 1000);
}

startTimer();
// 假设某个条件下,定时器应该停止,但未清除

解决方法

在不需要定时器或回调函数时,及时清除。

let timerId;

function startTimer() {
  timerId = setInterval(() => {
    console.log('Timer running');
  }, 1000);
}

function stopTimer() {
  clearInterval(timerId);
}

// 开始定时器
startTimer();
// 假设某个条件下停止定时器
stopTimer();

6. 闭包中的循环引用

情况描述

闭包和对象的相互引用可能导致循环引用,使得垃圾回收器无法正确回收内存。

示例代码

function createCircularReference() {
  const obj1 = {};
  const obj2 = { obj1 };
  obj1.obj2 = obj2;
}

createCircularReference();
// obj1 和 obj2 相互引用,无法被垃圾回收

解决方法

避免闭包和对象的循环引用,或者在不需要时显式解除引用。

function createCircularReference() {
  const obj1 = {};
  const obj2 = { obj1 };
  obj1.obj2 = obj2;
  
  // 在适当的时候解除循环引用
  obj1.obj2 = null;
  obj2.obj1 = null;
}

createCircularReference();

总结

  • 意外的全局变量:始终使用 varletconst 声明变量。
  • 闭包中的引用:在不再需要闭包时,显式解除对外部变量的引用。
  • DOM引用:移除DOM元素时,解除所有对该元素的引用。
  • 事件监听器未解除:在移除DOM元素之前,先解除其事件监听器。
  • 定时器和回调:在不需要定时器或回调函数时,及时清除。
  • 闭包中的循环引用:避免闭包和对象的循环引用,或在适当时解除引用。

通过遵循这些方法,可以有效地防止JavaScript中的内存泄漏问题。

标签:function,闭包,const,真题,内存,面试,引用,document,大厂
From: https://blog.csdn.net/weixin_43952318/article/details/140757585

相关文章

  • 大模型算法岗常见面试题100道(值得收藏)
    大模型应该是目前当之无愧的最有影响力的AI技术,它正在革新各个行业,包括自然语言处理、机器翻译、内容创作和客户服务等等,正在成为未来商业环境的重要组成部分。截至目前大模型已经超过200个,在大模型纵横的时代,不仅大模型技术越来越卷,就连大模型相关的岗位和面试也开始越来......
  • 2024年华为OD机试真题-找出作弊的人-(C++/Java/python)-OD统一考试(C卷D卷)
    2024华为OD机试真题目录-(B卷C卷D卷)-【C++JavaPython】  题目描述公司组织了一次考试,现在考试结果出来了,想看一下有没人存在作弊行为,但是员工太多了,需要先对员工进行一次过滤,再进一步确定是否存在作弊行为。过滤的规则为:找到分差最小的员工ID对(p1,p2)列表,......
  • 2024华为OD机试真题- 亲子游戏Python-C卷D卷-200分
    2024华为OD机试题库-(C卷+D卷)-(JAVA、Python、C++)题目描述宝宝和妈妈参加亲子游戏,在一个二维矩阵(N*N)的格子地图上,宝宝和妈妈抽签决定各自的位置,地图上每个格子有不同的糖果数量,部分格子有障碍物。游戏规则是妈妈必须在最短的时间(每个单位时间只能走一步)到达宝宝的位置,路上......
  • 【Golang 面试 - 进阶题】每日 3 题(三)
    ✍个人博客:Pandaconda-CSDN博客......
  • 【Golang 面试 - 进阶题】每日 3 题(四)
     ✍个人博客:Pandaconda-CSDN博客......
  • 【前端 · 面试 】HTTP 总结(十一)—— HTTPS 概述
    最近我在做前端面试题总结系列,感兴趣的朋友可以添加关注,欢迎指正、交流。争取每个知识点能够多总结一些,至少要做到在面试时,针对每个知识点都可以侃起来,不至于哑火。HTTPS前言通过前面内容的学习,相信大家对HTTP的概念、特点、请求方法及缓存等的......
  • Java面试题(容器)
    目录1、Java容器都有哪些?2、 Collection和Collections有什么区别3、List、Set、Map之间的区别是什么?4、 HashMap和Hashtable有什么区别?5、如何决定使用HashMap还是TreeMap?6、 说一下HashMap的实现原理?7、 ArrayList和LinkedList的区别是什么?8、 ......
  • 华为OD笔试机试 - 园区参观路径 (Java 2024年C卷D卷真题算法)
    华为OD机试(C卷+D卷)2024真题目录(Java&c++&python)题目描述园区某部门举办了FamilyDay,邀请员工及其家属参加;将公司园区视为一个矩形,起始园区设置在左上角,终点园区设置在右下角;家属参观园区时,只能向右和向下园区前进,求从起始园区到终点园区会有多少条不同的参观路径......
  • 华为OD笔试机试真题算法 - 密码解密 (Java 2024年C卷D卷)
    华为OD机试(C卷+D卷)2024真题目录(Java&c++&python)题目描述给定一段“密文”字符串s,其中字符都是经过“密码本”映射的,现需要将“密文”解密并输出。映射的规则(‘a’~‘i’)分别用(‘1’~‘9’)表示;(‘j’~‘z’)分别用(“10*”~“26*”)表示。约束:映射始终唯一。......
  • CSDN最新JAVA面试题集
    第一章-Java基础篇1、你是怎样理解OOP面向对象   难度系数:⭐面向对象是利于语言对现实事物进行抽象。面向对象具有以下特征:继承:继承是从已有类得到继承信息创建新类的过程封装:封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口多态性:多态性是指允......