首頁  >  文章  >  web前端  >  javascript變數作用域、記憶體、DOM洩漏等問題實例詳解

javascript變數作用域、記憶體、DOM洩漏等問題實例詳解

伊谢尔伦
伊谢尔伦原創
2017-07-18 10:31:521418瀏覽

作用域

變數沒有在函數內宣告或宣告的時候沒有帶var就是全域變量,擁有全域作用域,window物件的所有屬性都有全域作用域;在程式碼任何地方都可以訪問,函數內部聲明並且以var修飾的變數就是局部變量,只能在函數體內使用,函數的參數雖然沒有使用var但仍然是局部變數。

沒有區塊級作用域


// if语句:

<script type="text/javascript">
if(true){            //if语句的花括号没有作用域的功能。

var box = "trigkit4";
}
alert(box);//弹出 trigkit4
</script>

for迴圈語句也是如此。

變數的查詢

在變數的查詢中,存取局部變數要比全域變數來得快,因此不需要向上搜尋作用域鏈。
如下範例:


<script type="text/javascript">
   var name = "Jack";
   function setName(){
      var name = "trigkit4";
      return name; //从底层向上搜索变量
  }
  alert(setName());   
</script>

記憶體問題

javascript具有自動垃圾回收機制,一旦資料不再使用,可以將其設為"null"來釋放引用

循環引用

#  一個很簡單的例子:一個DOM物件被一個Javascript物件引用,同時又引用同一個或其它的Javascript對象,這個DOM對象可能會引發記憶體外洩。這個DOM物件的引用將不會在腳本停止的時候被垃圾回收器回收。要破壞循環引用,引用DOM元素的物件或DOM物件的參考需要被賦值為null。

閉包

在閉包中引入閉包外部的變數時,當閉包結束時此物件無法被垃圾回收(GC)。


var a = function() {
 var largeStr = new Array(1000000).join(&#39;x&#39;);
 return function() {
  return largeStr;
 }
}();

DOM洩漏

#當原有的COM移除時,子結點引用沒有移除則無法回收。


var select = document.querySelector;
var treeRef = select(&#39;#tree&#39;);
//在COM树中leafRef是treeFre的一个子结点
var leafRef = select(&#39;#leaf&#39;); 
var body = select(&#39;body&#39;);
body.removeChild(treeRef);
//#tree不能被回收入,因为treeRef还在
//解决方法:
treeRef = null;
//tree还不能被回收,因为叶子结果leafRef还在
leafRef = null;
//现在#tree可以被释放了。

Timers計(定)時器洩漏

定時器也是常見產生記憶體洩漏的地方:


for (var i = 0; i < 90000; i++) {
 var buggyObject = {
  callAgain: function() {
   var ref = this;
   var val = setTimeout(function() {
    ref.callAgain();
   }, 90000);
  }
 }
 buggyObject.callAgain();
 //虽然你想回收但是timer还在
 buggyObject = null;
}

調試記憶體

Chrome自帶的記憶體偵錯工具可以很方便地查看記憶體使用情況和記憶體外洩:
在Timeline -> Memory 點選record即可:

以上是javascript變數作用域、記憶體、DOM洩漏等問題實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn