前端初学者笔记 (四)内存泄漏及其解决

三种类型的常见 JavaScript 内存泄露:

一、由于声明变量时不严谨导致的全局变量污染
例如在函数中声明的:

function global(){
    kkk = 'this is it'
}

对于这样的字符串,JavaScript会处理成全局变量,相当于 window.kkk = 'this is it' 或在全局环境下声明的 var kkk = 'this is it'。

或者在函数中的this意外指向全局导致创建了全局对象

(x,y)=>{this.kkk='this is it',return x+y+kkk}()
//此处this指向了window/global,执行函数将意外创建全局变量kkk

解决办法:在 JavaScript 文件头部加上 'use strict',可以避免此类错误发生。启用严格模式解析 JavaScript ,避免意外的全局变量。

二、闭包

什么是闭包?函数内部封装函数,匿名函数可以访问父级作用域的变量。

function func() {
  var a = 1, b = 2;

  function closure() {
    return a + b;
  }
  return closure;
}

闭包的作用域链包含着它自己的作用域,以及包含它的函数的作用域和全局作用域。

闭包可以使得参数和变量在调用函数结束后,也不会被内存的垃圾回收机制清除,能留在内存中。

而这同时也是闭包的缺点:使得内存消耗增加,性能受到影响。

且在IE浏览器中可能会导致内存泄漏问题。

解决方法:在退出函数之前,将不使用的局部变量全部删除。

在该例中,在func()的最后,a=null,b=null 即可。

三、计时器setInterval()及其回调函数

计时器由于一直循环往复,里面的回调函数无法被内存垃圾回收机制回收,只有计时器停止才会被回收,消耗大量资源。

老版本的 IE 是无法检测 DOM 节点与 JavaScript 代码之间的循环引用,会导致内存泄露。

解决办法:clearInterval(id) 清除计时器 或 使用setTimeout()这种只执行一次的延时回调函数。

四、存在字典中的DOM节点

var elements = {
    image:document.getElementsByTagName('img')[0]
}
fuction setImg(){
    image.src = 'http//www.kkk.com/img23'
}

fuction remove(){
    //试图通过移除子节点的方法移除img节点,body是img的父节点
    document.body.removeChild(document.getElementsByTageName('img'));
}
remove();
//此时无法移除,仍旧存在一个全局的引用,image元素仍旧在内存中,不会被垃圾回收机制清除

保存下来的DOM节点不会被GC回收。造成内存消耗。

解决办法:删除这样的节点的时候需要把两个引用都清除。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值