当咱们用JS代码建立一个引用类型的时候(如下简称对象),JS引擎会在内存中开辟一块空间来存放数据,并把指针引用交给那个变量。内存是有限的,JS引擎必须保证当开辟的对象没用的时候,把所分配的内存空间释放出来,这个过程叫作垃圾回收,负责回收的叫作垃圾回收器。javascript
内存泄漏是指咱们已经没法再经过JS代码来引用到某个对象,但垃圾回收器却认为这个对象还在被引用,所以在回收的时候不会释放它。致使了分配的这块内存永远也没法被释放出来。若是这样的状况愈来愈多,会致使内存不够用而系统崩溃。java
如下几种状况会致使内存泄露闭包
当页面中元素被移除或替换时,若元素绑定的事件仍没被移除,在IE中不会做出恰当处理,此时要先手工移除事件,否则会存在内存泄露。函数
下面这种状况,咱们移除input
元素以后,但其绑定的事件仍在,垃圾回收器会认为这个对象仍是有用的,所以不会回收这个对象,这样就致使当初为这个对象分配的内存没法被释放。this
<div id="myDiv"> <input type="button" value="Click me" id="myBtn"> </div> <script type="text/javascript"> var btn = document.getElementById("myBtn"); btn.onclick = function(){ document.getElementById("myDiv").innerHTML = "Processing..."; } </script>
为了不这种状况的发生,咱们能够这样写指针
<div id="myDiv"> <input type="button" value="Click me" id="myBtn"> </div> <script type="text/javascript"> var btn = document.getElementById("myBtn"); btn.onclick = function(){ // 手动将 btn.onclick 指向 null, 这样在删除 input 对象时,就不会发生内存泄漏 btn.onclick = null; document.getElementById("myDiv").innerHTML = "Processing..."; } </script>
用innerHTML将对象置为空时,若是其中的元素被其余引用,也会发生内存泄漏。code
尽管咱们将div
的innerHTML
赋值为空,但由于引用p
指向div
中的p
元素,这时垃圾回收器会认为p
是有用的,由于被引用着,因此不会回收p
占用的内存,致使内存泄漏。对象
<div id='myDiv'> <p id='myP'>innerHTML<p> </div> <script type="text/javascript"> var div = document.getElementById("myDiv"); var p = document.getElementById("myP"); div.innerHTML = ''; </script>
闭包的重要做用之一就是保持状态事件
正常状况下,一个函数运行结束,其内部的变量就应该被释放。但下面的状况是,函数outer
返回一个匿名函数,这个函数引用变量obj
。这样致使函数outer
运行结束后,它的变量obj
并无被释放。ip
function outer(){ var obj = {name:'xiaoxiong'}; return function(){ console.log(obj); } }
你能够经过加上
'use strict'
启用严格模式来避免这类问题, 严格模式会阻止你建立意外的全局变量
函数运行结束,变量仍然存在,致使泄漏。
function work() { bar = "this is a hidden global variable"; } // 上面的函数等价于 function work(arg) { window.bar = "this is an explicit global variable"; }
如今咱们总结一下,致使内存泄漏的缘由大体能够分为两种
致使这两种状况的根本缘由就是有其余变量引用这些元素。让垃圾回收器认为这个元素仍是有用的,所以想避免内存泄漏,咱们应该, 要删除一个元素,就要保证在删除这个元素以前,这个元素不被其余其余元素引用(将引用这个元素的指针指向其余元素或置空)