当涉及全局变量时,Javascript中的垃圾回收

Garbage collection in Javascript when Global variables are involved

本文关键字:Javascript 全局变量      更新时间:2023-09-26

所以我正在用html5的新<Audio>标签构建一个音频播放器,但我正在用javascript声明、初始化和操作<Audio>序列(参见此处的示例(。基本上,<Audio>标签一次只允许播放一首歌,并且很容易操作,所以每当"Next"、"Previous"、"Shuffle","或者甚至只是选择了另一首歌,我用一个新的url替换了音频标签的src,其中包含了这首新歌

加载后,我这样声明变量song

var song= new Audio("url");

接下来的每一首歌都是对song的改写,就像这样:

song= new Audio("new url");

该方法最终起到了作用,但对于每个歌曲实例,监视清理范围及其属性max(确定范围长度(和值(确定索引在范围内的位置(的事件处理程序都与song的每个先前实例相关联。我不得不重新分配事件侦听器,每次都重新分配这些属性,在播放了一定数量的歌曲后,性能确实开始受到影响。

我的问题是,即使javascript有一个针对不再使用的内存的垃圾收集器,song的实例都有与其关联的全局事件侦听器,所以我不认为它们会被自动删除。有没有办法在歌曲被覆盖后立即删除它们?有没有一种完全不同但更好的方法来实现我想要的?

感谢您的帮助和建议!

我决定采取不同的方法来解决这个问题,以完全避免垃圾收集问题。虽然这不一定是对我问题的直接回答,但它是一个替代的、有效的解决方案。

最后,我简单地重新分配了audioInstance.src,假设用一个新的实例覆盖每个Audio实例,其中包含一个新url作为src。最初,歌曲无法播放,或者自动播放器中涉及元数据的某些部分无法工作,但我找到了这个链接,它解释了更改audio.src时必须首先调用audio.load();

此:

var audio =  new Audio(url);
addListeners(); //only need to do this once, since the listeners always point to audio declared above
var duration=audio.duration;
audio.play();
audio.src = newurl;
audio.load();
duration=audio.duration;
audio.play();

取而代之的是:

var audio = new Audio(url);
addListeners();
var duration=audio.duration;
audio.play();
audio = new Audio(newUrl);
addListeners(); //need to do this a second time, since the old listeners will always be attached to the old audio instance
duration=audio.duration;
audio.play();

这帮助我获得了所需的最终结果,并消除了为Audio对象的多个实例声明多个侦听器时出现的垃圾收集问题。

一旦变量不再在作用域中,它们就会被垃圾收集。全局变量的糟糕之处在于,它们从来没有资格进行垃圾收集。我最好的建议是避免全局变量,并始终将范围限制在需要的