未加星标

[js点滴]javaScript闭包引起的问题及分析

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二05 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏
1、什么是闭包、以及闭包所涉及的作用域链这里就不说了。 2、javascript垃圾回收机制

JavaScript不需要手动地释放内存,它使用一种自动垃圾回收机制(garbage collection)。当一个对象无用的时候,即程序中无变量引用这个对象时,就会从内存中释放掉这个变量。

var s = [ 1, 2 ,3]; var s = null; //这样原始的数组[1 ,2 ,3]就会被释放掉了。 3、循环引用

三个对象 A 、B 、C

A à B à C :A的某一属性引用着B,同样C也被B的属性引用着。如果将A清除,那么B、C也被释放。

A à B à C à B :这里增加了C的某一属性引用B对象,如果这是清除A,那么B、C不会被释放,因为B和C之间产生了循环引用。

var a = {}; a.pro = { a:100 }; a.pro.pro = { b:100 }; a = null ; //这种情况下,{a:100}和{b:100}就同时也被释放了。 var obj = {}; obj.pro = { a : 100 }; obj.pro.pro = { b : 200 }; var two = obj.pro.pro; obj = null; //这种情况下 {b:200}不会被释放掉,而{a:100}被释放了。 4、循环引用和闭包 function outer(){ var obj = {}; function inner(){ //这里引用了obj对象 } obj.inner = inner; }

这是一种及其隐蔽的循环引用,。当调用一次outer时,就会在其内部创建obj和inner两个对象,obj的inner属性引用了inner;同样inner也引用了obj,这是因为obj仍然在innerFun的封闭环境中,准确的讲这是由于JavaScript特有的“作用域链”。

因此,闭包非常容易创建循环引用,幸运的是JavaScript能够很好的处理这种循环引用。

5、IE中的内存泄漏

IE中的内存泄漏有好几种,这里有详细的解释( http://msdn.microsoft.com/en-us/library/bb250448.aspx ),园子里也有翻译了( http://www.cnblogs.com/birdshome/archive/2006/05/28/ie_memoryleak.html )。

这里只讨论其中一种,即循环引用所造成的内存泄漏,因为,这是一种最普遍的情况。

当在DOM元素或一个ActiveX对象与普通JavaScript对象之间存在循环引用时,IE在释放这类变量时存在特殊的困难,最好手动切断循环引用,这个bug在IE 7中已经被修复了( http://www.quirksmode.org/blog/archives/2006/04/ie_7_and_javasc.html )。

“IE 6 suffered from memory leaks when a circular reference between several objects, among which at least one DOM node, was created. This problem has been solved in IE 7. ”

如果上面的例子(第4点)中obj引用的不是一个JavaScript Function对象(inner),而是一个ActiveX对象或Dom元素,这样在IE中所形成的循环引用无法得到释放。

function init(){ var elem = document.getElementByid( 'id' ); elem.onclick = function(){ alert('rain-man'); //这里引用了elem元素 }; }

Elem引用了它的click事件的监听函数,同样该函数通过其作用域链也引用回了elem元素。这样在IE中即使离开当前页面也不会释放这些循环引用。

6、解决方法

基本的方法就是手动清除这种循环引用,下面一个十分简单的例子,实际应用时可以自己构建一个addEvent()函数,并且在window的unload事件上对所有事件绑定进行清除。

function outer(){ var one = document.getElementById( 'one' ); one.onclick = function(){}; } window.onunload = function(){ var one = document.getElementById( 'one' ); one.onclick = null; };

其它方法(by: Douglas Crockford )

/**
* 遍历某一元素节点及其所有后代元素
*
* @param Elem node 所要清除的元素节点
* @param function func 进行处理的函数
*
*/
function walkTheDOM(node, func) {
func(node);
node = node.firstChild;
while (node) {
walkTheDOM(node, func);
node = node.nextSibling;
}
}
/**
* 清除dom节点的所有引用,防止内存泄露
*
* @param Elem node 所要清除的元素节点
*
*/
function purgeEventHandlers(node) {
walkTheDOM(node, function (e) {
for (var n in e) {
if (typeof e[n] === ‘function’) {
e[n] = null;
}
}
});
}

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

主题: JavaScriptJava变量
分页:12
转载请注明
本文标题:[js点滴]javaScript闭包引起的问题及分析
本站链接:http://www.codesec.net/view/484646.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(25)