[javascript]會造成memory leak的幾種常見注意事項寫法

[javascript]會造成memory leak的幾種常見注意事項寫法

前言

在javascript的世界裡面,其實很容易造成memory leak的問題,在以前沒有spa的時代,其實這種造成memory leak的問題不大,除非是某個頁面一直開著從不重整也沒有去別的頁面才會造成網頁整個當掉,不過當網頁走向spa的時候,就要特別注意memory leak的問題,正常狀態下如果是用framework如angular的話,官方都會幫你處理好這類的問題,也會提醒你有哪些地方該注意(不過這也不是絕對的,我就曾經看過angularjs寫得不像angularjs,.net mvc寫得像.net web form的),而如果是自己寫原生javascript或jquery的話,有些事情我們就都得要自己處理和留意了,接著就來舉一些我在網路上收集,比較會造成memory leak的一些問題,這些問題是屬於原生javascript的,不一定適用於任一框架,而且也不一定只僅限於es5或es6等等。

導覽

  1. 未宣告變數就給值
  2. 宣告全局變數注意事項
  3. 計時器使用的問題
  4. javascript監聽事件需要釋放
  5. 結論

未宣告變數就給值

在javascript裡面,宣告變數有var,let,const等等的方式,但是javascript就像沒有宣告,也能直接給值,這就造成了這個變數馬上變成全局的方式,當然如果你有使用嚴格模式('use strict';),就不會發生這個問題

  <script>
    function init(){
      bar = 'this is test';
    }
  </script>

正確應該改成

  <script>
    function init(){
     this.bar = 'this is test';      
    }
  </script>

或者

  <script>
    function init(){
     var bar = 'this is test';      
    }
  </script>

宣告全局變數注意事項

當我們宣告某個變數的時候,如果是宣告成全局的話,如果我們沒有手動去設為null,他的內存就會一直保存在memory裡面。

  <script>
    var arr=[1,2,3];
    function init(){
     console.log(arr);
    }
  </script>

正確

  <script>
      var arr = [1, 2, 3];
      function init() {
        console.log(arr);
      }
      arr=null;
  </script>

計時器使用的問題

有時候我們不小心設了一個變數,然後在計時器裡面有用到的話,就永遠也不可能釋放了,當然有時候我們確實必須得宣告一個全局變數來使用,但是必須和不小心可是差很多的。

  <script>
      var resource='default';
      function init() {
        setInterval(function(){
          resource='setTime';
          console.log(resource);
        },1000);
      }
      resource=null;
  </script>

特別注意一下不管是迴圈或遞迴或這種計時器的案例,都很容易造成memory快速長大,比如重覆註冊事件啦,重覆的呼叫原本已經釋放的資源啊,所以需要特別的注意。

javascript監聽事件需要釋放

如果有學過rxjs的人都知道,我們只要訂閱了,就必須要適時的取消定閱,當然javascript監聽事件也是一樣的道理,甚至有時候我們不經意的去重覆監聽事件,又忘了移除監聽就更嚴重了。

var button= document.getElementById('button');
button.addEventListener('click', onClick);
//一旦監聽如果不再用到,記得去移除監聽
button.removeEventListener('click', onClick);

結論

其實這些會造成memory leak的例子,我幾乎都是從網路上得到的知識,有些是平常自己的小筆記,最後想說整理一下寫出來,就不用在保留自己隨意亂寫的小筆記,以後如果有什麼看到新的知識,也會再回來修改並補上新的部份,如果有任何該注意我沒寫到,或者不正確的地方,再請留言給筆者。