javascript - 以下执行的js代码中,代码执行完毕,变量得到释放了吗?
伊谢尔伦
伊谢尔伦 2017-04-10 14:24:04
[JavaScript讨论组]

小弟也是初学JS,请教一下各位大牛!

代码片段:

(function() {
    var li = document.getElementById('nav').getElementsByTagName('li'),
        i = 0;
    for (; i < li.length; i++) {
        li[i].index = i;
        li[i].onmouseover = function() {
            for (var j = 0; j < li.length; j++) {
                li[j].getElementsByTagName('a')[0].className = '';
            }
            li[this.index].getElementsByTagName('a')[0].className = 'current';
        }
    }
}());

我就是想问下这里的 li 变量,当函数执行完成时,有没有得到内存的释放?

我个人认为觉得并没有得到释放,因为 onmouseouver 事件,闭包引用了 li 外面作用域的变量,所以垃圾回收器,标记一直是1,所以没有得到释放。

如果要想释放内存,以上代码应该怎样改呢?

伊谢尔伦
伊谢尔伦

小伙看你根骨奇佳,潜力无限,来学PHP伐。

全部回复(4)
高洛峰

先说结论:这段代码糟糕到没必要关心内存释放,而且这里的li这个内存如果硬释放掉了只会性能更糟糕(必然要在匿名函数体内再多跑一次DOM操作)

  • 能用CSS就不用JS
  • 不要在循环内部写任何匿名函数,尤其避免在for循环内部的匿名函数
  • 高频率DOM事件要限频

最好的方案是用CSS:hover伪类,无论从内存、效率、代码维护上来说都是比较好的

如果非要用JS的话,那么有两个优化可以做

  • 把事件绑在父元素上,利用冒泡机制实现(削减listener数量)
    for里面写匿名函数,除了内存问题以外,还会有闭包问题(比如例子的匿名函数体内如果用i问题就来了)
    涉及到DOM事件绑定,事情就更糟糕了(记住DOM事件的绑定越少越好,绑DOM事件是很昂贵的,尤其是mouseover这样的高频率事件)
  • 由于mouseover是个触发非常频繁的事件,可以利用类似_.throttle()的机制限制运行频率,减少DOM操作频率
黄舟

这里的 li 变量,当函数执行完成时,有没有得到内存的释放?

没有

这个算内存泄露吗?
不算,当你不再需要的内存,它已经没有被引用了,但却没释放,这意味着除非程序结束,不然它永远没法释放了,这叫内存泄露。

li变量不释放有什么问题
没什么问题

高洛峰

除了IE的部分对象(BOM,DOM)采用引用计数的方式以外,其它浏览器都完全采用标记清除方式来进行垃圾收集。

不使用匿名函数。改用一个实例对象保存指向li的指针,通过该对象引用li,最后用delete操作符或者赋值为null来解除对li的引用。

伊谢尔伦

这个问题我很认真地看到,i被提出来声明变量的时候,就一点兴趣都没了,发完关闭此页。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号