小夥伴們都知道,js中的對象屬於引用類型,單純的用等號賦值,其實複製的是引用地址,真正指向的仍是堆內存中同一個值,當一個值的內部屬性變化時,另外一個值因爲指向的是堆內存中的同一個值,因此也會發生變化。這每每是咱們不想要的結果,我也在項目中由於這個吃過大虧,因此一塊兒來討論討論吧!數組
經過JSON.stringify
,JSON.parse
能夠實現深拷貝,可是有個坑得注意下,在序列化JavaScript對象時,全部函數和原型成員會被有意忽略。看下面這個案例:bash
var a = {
name:"西瓜",
run:function(){
console.log(123)
}
}
console.log(JSON.parse(JSON.stringify(a)));
複製代碼
能夠看出,在拷貝的過程當中,對象中的
run
方法不見了。
話很少說,直接上代碼:函數
//主入口函數
function deepCopy(obj){
if(typeof obj === "object"){
//是一個數組
if(Array.isArray(obj)){
return copyArray(obj);
}else{
//是一個對象
return copyObj(obj);
}
}
}
//若是是對象類型的,執行該函數
function copyObj(obj){
var newObj = {};
for(let key in obj){
if(typeof obj[key] === "object"){
//obj[key]仍是屬於object類型的話,遞歸執行deepCopy
newObj[key] = deepCopy(obj[key]);
}else{
newObj[key] = obj[key];
}
}
return newObj;
}
//若是是數組類型類型的,執行該函數
function copyArray(array){
var newArr = [];
array.forEach((item,index)=>{
//item仍是屬於object類型的話,遞歸執行deepCopy
if(typeof item === "object"){
newArr.push(deepCopy(item));
}else{
newArr.push(item);
}
});
return newArr;
}
//測試
var testObj = [{
name:"西瓜",
info:{
age:10,
adress:"杭州"
}
},
"哈哈哈哈哈",
{
run:function(){
console.log(123)
}
}
];
var deepObj = deepCopy(testObj);
testObj[1] = "我改變了數組裏面的一個值";
console.log(testObj);
console.log(deepObj);
複製代碼
運行結果以下:測試
結果中看到,deepObj
是使用深拷貝函數後獲得的結果,在這以後去修改testObj
的值,deepObj
的值並無發生改變。說明深拷貝成功啦! ###總結 在實現深拷貝的過程當中,也能夠複習一下遞歸的知識,仍是挺好的!小夥伴們也去試試吧!ui