JS基礎之堆棧內存的區別

堆棧內存的區別

堆棧內存的區別(看圖)

	let a = 12;
    let b = a;
    let c = {name: 'xiaoHua'};
    b = 13;
    console.log(a, c)
——————————————————————————————————————————————
    let a = {n:1};
    let b = a;
    a.x = a = { // 像這種連續等於要從左往右依次賦值
    n:2
    };    
    console.log(a.x, b);

在這裏插入圖片描述
QQ圖片20191108112407.png

堆內存和棧內存

打開一個頁面,瀏覽器會形成兩個虛擬的內存:堆內存、棧內存
棧內存存儲了啥:變量、基本數據類型值、地址
堆內存存儲了啥:存儲了引用數據類型的值
PS:全局作用域、私有作用域都是棧內存,爲代碼執行提供必要的環境,理論上來說,存儲的東西越少,運行的越快

堆棧內存銷燬

  • 堆內存回收

    堆內存回收:GC垃圾回收機制;在瀏覽器內置了一個gC程序,這個程序會每隔一段時間執行一次;

    • 谷歌瀏覽器-標記法:瀏覽器每隔一段時間要對所有的空間地址類型進行檢測,檢查該地址是否被佔用;如果沒有佔用,那麼久立即回收掉
    • IE和火狐-計數法:瀏覽器採用計數的規則,如果空間地址被佔用一次,那這個空間地址就默認+1,每空閒一次,空間地址就默認-1,如果瀏覽器發現有爲0的空間地址,就把其回收
  • 堆內存銷燬

		var obj = {};
        obj = null;
        // 谷歌瀏覽器:
  • 棧內存回收==>作用域銷燬
  • 棧內存的銷燬:立即銷燬、不銷燬 、不立即銷燬
    • 作用域就是棧內存:全局作用域、私有作用域
      • 全局作用域的銷燬: 一般情況情況不銷燬,除非把當前頁面關閉,整個作用域就銷燬了
      • 私有作用域的銷燬:立即銷燬、不銷燬 、不立即銷燬
        • 不銷燬:
          • (1)函數(包括自執行函數)要return一個引用數據類型值,(2),return要被外界接收
          • 如果當前作用域有個空間地址,被函數體外的東西佔用着,那麼這個棧內存就不能銷燬;
          • 對象鍵值對的屬性名對應的是個自執行函數並且返回值的是個函數,自執行函數作用域不銷燬。
        • 不立即銷燬:fn()()return一個小函數,馬上讓小函數執行,這時候外界的作用域不能立即銷燬,他要等待小函數執行完成之後再銷燬
        • 立即銷燬:不能同時滿足上邊的兩個條件,作用域就銷燬了
          • 作用域銷燬的例子
        /*         var i = 5;
        function fn(i) { // 1  2   3
            return function (n) { // 2         7  
                console.log(n + (++i)); // 4    10
            }
        }
        var f = fn(1);
        f(2);
        fn(3)(4);
        fn(5)(6);
        f(7);
        console.log(i); // 5

QQ圖片20191121155612.png


        // function fn(){
        //     var name = 'jinYu',
        //     age = 18; 
        // }
        // fn();
        // fn();

        // (1)函數要return一個引用數據類型值;(2)return的值要被外界接收
        
        // function fn(){
        //     var name = 'jinYu',
        //     age= 16;
        //     return {
        //         name: name,
        //         age: age
        //     }
        // }
        // var res = fn()

    // 不銷燬作用域
    // 1. 返回一個引用的數據類型值
    // 2. 返回的值需要被外界接受
    // var num =2;
    // function fn(){
    //     var num =1;
    //     return function(){
    //         console.log(num); // 1
    //     }
    //     return {}
    // }
    // var f = fn()
    // f();

    // 2. 如果當前作用域有個空間地址,被函數體外的東西佔用着,那麼這個棧內存就不能銷燬;
    // function fn(){
    //     // oLis[i].onclick = function(){
    //     // }
    //     // var obj = {};
    //     // obj.a = function(){
            
    //     // }
    // }
    // fn()


    // 不銷燬
    // var obj = {
    //     num:1,
    //     fn:(function(){
    //         // 不銷燬
    //         return function(){

    //         }
    //     })()
    // }


    // 不立即銷燬
        function fn(){
            var a = 12;
            return function(){
                console.log(a)
            }
        }
        fn()()
// 當外層大函數執行完成之後不能立即銷燬,他要繼續等待裏面的小函數執行完成銷燬之後,大函數在銷燬
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章