js對象的淺拷貝與深拷貝


淺拷貝和深拷貝都是對於JS中的引用類型而言的,淺拷貝就只是復制對象的引用(堆和棧的關系,原始(基本)類型Undefined,Null,Boolean,Number和String是存入堆,直接引用,object array 則是存入桟中,只用一個指針來引用值,如果拷貝后的對象發生變化,原對象也會發生變化。只有深拷貝才是真正地對對象的拷貝。

1、淺拷貝

默認是淺拷貝,只是將地址進行了復制,示例如下:

//淺拷貝
var obj1={name:"cat"};
var obj2=obj1;

obj2.name="pig";

console.log(obj1.name);
console.log(obj2.name);

結果:pig

 

2、深拷貝

深拷貝就是對目標的完全拷貝,不像淺拷貝那樣只是復制了一層引用,就連值也都復制了。

只要進行了深拷貝,不會相互影響。

方法一:利用 JSON 對象中的 parse 和 stringify;

注:如果對象中含有一個函數時(很常見),就不能用這個方法進行深拷貝

var obj1 = {
    name: "cat",
    show:function(){
        console.log(this.name);
    }
};
var obj2 = JSON.parse(JSON.stringify(obj1));

obj2.name = "pig";

console.log(obj1.name);
console.log(obj2.name);

obj1.show();
obj2.show();  //函數被丟失

方法二:利用遞歸來實現每一層都重新創建對象並賦值

//對象
var obj1 = {
    name: "cat",
    show:function(){
        console.log(this.name);
    }
};

//這種深拷貝函數不會丟失
function deepClone(obj) {
    let objClone = Array.isArray(obj) ? [] : {};
    if(obj && typeof obj === "object") {
        for(key in obj) {
            if(obj.hasOwnProperty(key)) {
                //判斷ojb子元素是否為對象,如果是,遞歸復制
                if(obj[key] && typeof obj[key] === "object") {
                    objClone[key] = deepClone(obj[key]);
                } else {
                    //如果不是,簡單復制
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
}
var obj3=deepClone(obj1);
//輸出cat
obj3.show();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM