《JavaScript高級程序設計》筆記:變量、做用域、內存問題

1、寫在前面

最近研究了建立Android虛擬機、vscode結合weex開發Android APP、Vmware裝MAC虛擬機的事,看的內容不夠多,接下來加油javascript

2、變量、做用域和內存問題

2.1 基本類型、引用類型

  • 變量類型:前端

    • 基本類型: 簡單數據段,按值訪問的,可操做變量中的實際值
    • 引用類型:對象,按引用訪問,操做對象的引用,能動態添加屬性
  • 變量複製:java

    • 基本類型:直接分配兩個內存空間,互不影響
    • 引用類型:複製了指針,指向堆中同一對象,相互影響
  • 傳參(見示例):web

    • 基本類型傳值,互不影響
    • 引用類型傳地址,相互影響
// 示例
function setName(obj) {
    // 指向person,添加屬性name
    obj.name = "Nicholas";
    // 指針指向新的內存空間
    obj = new Object();
    obj.name = "Greg";
    
    // 函數執行完畢後,局部對象當即銷燬
}

var person = new Object();
setName(person);
alert(person.name);    //"Nicholas"
  • 檢測類型數組

    • typeOf特殊:null返回object
    • instanceof:引用類型檢測,(某實例) instanceof (某類型)

2.2 執行環境、做用域

  • 執行環境:定義變量或函數有權訪問的其餘數據範圍,決定行爲。中有變量對象,保存環境中定義的全部變量和函數,環境銷燬,變量、函數銷燬瀏覽器

    • 全局執行環境,web中爲window對象
    • 局部執行環境,執行流進入函數,函數環境被推入環境棧,執行後,棧將其環境彈出,控制權返回以前的執行環境
  • 做用域鏈: 在環境中執行代碼,會建立變量對象的做用域鏈,保證(有權訪問當前環境的)變量和對象有序訪問
做用域鏈的前端,始終都是當前執行的代碼所在環境的變量對象。若是這個環境是函數,則將其活動對象(activation
object)做爲變量對象。活動對象在最開始時只包含一個變量,即arguments對象(這個對象在全局環境中是不存在的)。做用域鏈中的下一個變量對象來自包含(外部)環境,而再下一個變量對象則來自下一個包含環境。這樣,一直延續到全局執行環境;全局執行環境的變量對象始終都是做用域鏈中的最後一個對象
  • 標識符解析:沿做用域鏈一級一級搜索標識符。從做用域鏈前端開始,逐級向後,直到找到標識符爲止
  • 內外關係:weex

    • 內部環境能夠經過做用域鏈訪問全部外部環境,外部環境不能訪問內部環境中的任何變量或函數
    • 每一個環境能夠向上級搜素,但不能向下搜索進入另外一個執行環境

2.3 延長做用域鏈

在做用域鏈前端加臨時變量對象,執行後移除函數

  • try-catch中catch
  • with
function aaa( ) {
    var qs = '?id=12';
    // 引用location,with內部可用location的全部屬性和方法
    with(location) {
        // href爲locaiton.href
        var url = href + qs;
    }
   // 在aaa( )內可拿到with( )內定義的url
    return url;
}
  • catch特殊狀況:IE8之前catch的錯誤對象會添加至執行環境的變量對象,catch外也能訪問(IE9修復了)

2.4 沒有塊級做用域

{ } 封閉的代碼塊中定義的變量,執行後沒有被銷燬,依舊存在於{ }外部執行環境中性能

  • 聲明變量優化

    • var:自動添加到最接近的環境中。沒有var直接聲明,添加到全局環境中(嚴格模式下致使錯誤,不推薦)
  • 查詢標識符

    • 從做用域鏈前端開始,向上逐級查詢,直至匹配爲止(先自身再向上)
    • 訪問局部變量比訪問全局變量更快

2.5 垃圾收集

執行環境管理着代碼執行過程當中使用的內存
自動垃圾收集機制:實現所需內存分配、無用內存回收,自動管理。固定時間間隔,週期性檢索再也不繼續使用的變量,打標記,釋放其佔用的內存

  • 回收策略

    1. 標記清除(主流)

      • 變量進入環境、離開環境,標記不一樣
      • 標記方式:翻轉某位,或以環境列表、離開環境列表區分,或其餘
      • 運行機制:內存中所有變量加標記,再去掉環境中的、被環境中引用的變量的標記,剩下還有標記的,準備刪除,垃圾收集器清除內存,銷燬值,回收空間
    2. 引用計數(不常見)

      • 跟蹤每一個值被引用的次數
      • 計數規則:引用類型的值賦給一個變量,引用次數加一;已經引用的變量再也不引用它,引用次數減一
      • 運行機制:垃圾收集器運行,釋放引用次數爲0的值所佔的內存。
      • 特殊狀況:

        • 循環引用(例:兩對象間相互引用,則引用次數永不爲0,沒法銷燬)
        • IE9以前,BOM、DOM對象以COM(使用引用計數策略)形式實現,循環引用後刪除DOM,對應值也不會回收(經過賦值null,手動斷開循環引用解決)。IE9後,BOM、DOM轉爲真正的js對象,避免了該問題
  • 性能問題

    • IE7以前:內存分配量達到任一臨界值(256變量、4096對象數組、64K字符串)則回收,缺點:如一直在臨界值之上,則一直回收
    • IE7修正:臨界值動態修正,初始與以前相等,回收的分配量低於15%,臨界值加倍,回收的內存分配量85%,臨界值恢復初始
    • 手動觸發方式(不推薦):
// 手動觸發方式
// IE
window.CollectGarbage();
// Opear7~
window.opera.collect();
  • 管理內存

    • 內存分配:給web瀏覽器的少於給桌面應用的,防止系統崩潰
    • 優化內存佔用:只保存必要數據,不用的置null(解除引用,給全局中的用,局部的會自動銷燬),等待下一次垃圾回收
相關文章
相關標籤/搜索