js對象的深淺拷貝

js對象的深淺拷貝

針對於JavaScript的對象和數組(數組也是對象)淺拷貝只是引用,內存不變;而深拷貝就是遞歸賦值。
深拷貝是不同內存,相互獨立。而淺拷貝會影響

//1.循環複製數組
var arr = [1,2,3],arr2 = [];
for(var i=0;i<arr.length;i++) {
    arr2[i] = arr[i];
}

//2.還可以用一句簡單的代碼實現上面的深拷貝:
Array.prototype.push.apply(arr2,arr);

//3.先把這個對象轉化爲字符串,在拷貝,再轉化回來即可
JSON.parse(JSON.stringify(obj))

別急着走,利用window.JSON的方法做深拷貝存在2個 缺點:

  • 如果你的對象裏有函數,函數無法被拷貝下來
  • 無法拷貝對象原型鏈上的屬性和方法

例如下面這種情況:對象裏包含函數

var o1 = {
    name:"小明",
    age:12,
    city:"廣州",
    schools:["小學","中學","大學"],
    say:function(){
            alert(this.name);
    }
}
//下面的方法可以實現 深深度複製(複製包括函數)
function deepClone(oldObj){
        var newObj = {};
        for(var key in oldObj){
                if(oldObj.hasOwnProperty(key)){
                        if(oldObj[key].constructor == Array){ //判斷oldObj[key]值是否數組/對象
                                newObj[key] = oldObj[key].slice();
                        }else if(oldObj[key].constructor == Object){
                                newObj[key] == deepClone(oldObj[key]);
                        }else{
                                newObj[key] = oldObj[key];
                        }
                }
        }
        return newObj;
}
var o2 = deepClone(o1);

當然,你明確知道他們的缺點後,如果他的缺點對你的業務需求沒有影響,就可以放心使用了,一行原生代碼就搞定。
目前我在開發業務場景中,大多還真可以忽略上面2個缺點。往往需要深拷貝的對象裏沒有函數,也不需要拷貝它原型鏈上的屬性。

js堆棧

由於js中的對象都是複雜數據類型,這種數據在內存中存儲的時候,存放在堆中。當簡單賦值的時候,其實是將該對象的指針指向同一個堆地址。
簡單的數據類型存放在棧中,當對簡單的數據類型進行賦值的時候,其實就是直接在棧中新開闢一個地方專門存儲一樣的值。

數據結構裏的堆棧:
棧(stack): 由編譯器自動分配, 存放函數的參數值, 局部變量的值等. 其操作方式類似於數據結構中的棧.
堆(heap): 一般由程序員分配釋放, 若程序員不釋放, 程序結束時可能由OS回收. 這裏OS是指: 操作系統(Operating System)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章