2014-07-10 61 views
1

所以我建立與HTML5的新<Audio>標籤的音頻播放器,但我的「M聲明,初始化和操縱<Audio>序列的所有的JavaScript(See example here)。基本上<Audio>標籤一次只允許播放一首歌曲並且易於操作,因此無論何時「下一個」,「上一個」,「隨機播放」,或者甚至只是選擇另一首歌曲,我都會將音頻標籤的src替換爲新的。網址,包含新曲垃圾收集在Javascript中當全局變量參與

一旦負載,我聲明的變量song像這樣:

var song= new Audio("url"); 

和所有其他下列選定的歌曲只是一個像這樣的song覆蓋:

song= new Audio("new url"); 

的方法已經結束了工作,但每首歌例如,事件處理監控之類的range擦洗和其確定範圍長度的屬性max以及確定索引落在該範圍上的位置的值與以前的每個song實例相關聯。我不得不重新分配事件監聽器,並且每次和一定量的歌曲後重新分配這些屬性,性能開始受到影響。

我的問題是,即使javascript有一個垃圾收集器,目標內存不再使用,song的實例都具有與它們相關的全局事件偵聽器,所以我不認爲它們會被自動刪除。一旦歌曲被覆蓋,是否有一些方法可以刪除它們?是否有完全不同但更好的方法來完成我想要的?

感謝您的任何幫助和建議!

回答

0

變量一旦不在範圍內就會被垃圾回收。 關於全局變量的糟糕之處在於它們絕對不符合垃圾回收的條件。我最好的建議是避免全局變量,並總是將範圍限制在需要的範圍內

+0

當不再有對象**的任何引用**時,由全局變量引用的對象可用於垃圾回收。因此用一個對另一個對象的引用替換一個對象的引用使得第一個對垃圾回收可用(假設沒有其他引用)。 – RobG

+0

是的,但全球變量總是會有一個參考,因爲他們真的是window.someVar – TGH

+0

@RobG好吧,我明白了什麼意思。您正在討論切斷全局變量與全局變量之間的關係。 – TGH

0

我決定採取不同的方法解決問題,以避免垃圾收集問題。雖然這不一定是對我的問題的直接回答,但它是一種替代的工作解決方案。

我結束了簡單的重新分配audioInstance.src,假設覆蓋每個Audio實例與一個新的,包含一個新的url作爲src。最初,歌曲不會播放,或涉及元數據的汽車播放器的某些部分不起作用,但我找到了this鏈接,這說明您必須先撥打audio.load();當您更改audio.src時。

此:

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對象。