淺拷貝和深拷貝都是對於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();