本文將手動(dòng)實(shí)現(xiàn)引用類型的深拷貝
關(guān)于值類型與引用類型可閱讀下方文章:
JS基礎(chǔ)類型直通車(chē):
Js基礎(chǔ)知識(shí)-變量類型
Js基礎(chǔ)知識(shí)-typeof運(yùn)算符
let obj1={
name:'王',
age:23,
address:{
city:'河南省鄭州市'
},
hobby:['play','eat']
}
let obj2=obj1
console.log(obj1.name) // 王
obj2.name='李'
console.log(obj1.name) // 李
由于直接將obj1直接賦值給了obj2,此時(shí)他們的指針地址是相同的隶债,所以當(dāng)obj2改變時(shí),obj1的值也會(huì)改變。
如何將obj1賦值給obj2,修改obj2的值obj1得值不會(huì)改變扑馁?
- 創(chuàng)建方法deepClone,將返回一個(gè)值作為方法的返回值
/**
* 深度克隆
* @param {object} obj 需要克隆的對(duì)象/數(shù)組
*/
function deepClone(obj={}){
return obj
}
- 檢查傳入的參數(shù)類型是否為引用類型憎乙,不是的話將參數(shù)直接返回
/**
* 深度克隆
* @param {object} obj 需要克隆的對(duì)象/數(shù)組
*/
function deepClone(obj={}){
if(typeof obj!=='object'||obj==null){
return obj
}
}
- 處理參數(shù)為引用類型,檢查是否為數(shù)組队秩,定義新的變量
/**
* 深度克隆
* @param {object} obj 需要克隆的對(duì)象/數(shù)組
*/
function deepClone(obj={}){
if(typeof obj!=='object'||obj==null){
return obj
}
let result // 將要返回的變量
if(obj instanceof Array){
result=[] // 如果Obj為數(shù)組庄涡,則將返回定義為空數(shù)組
}else{
result={} // 如果Obj為對(duì)象择浊,則將返回定義為空對(duì)象
}
}
- 遍歷賦值
會(huì)用到遞歸戴卜,如果不清楚可以將每一個(gè)obj的值進(jìn)行打印。
/**
* 深度克隆
* @param {object} obj 需要克隆的對(duì)象/數(shù)組
*/
function deepClone(obj={}){
if(typeof obj!=='object'||obj==null){
return obj
}
let result // 將要返回的變量
if(obj instanceof Array){
result=[] // 如果Obj為數(shù)組琢岩,則將返回定義為空數(shù)組
}else{
result={} // 如果Obj為對(duì)象投剥,則將返回定義為空對(duì)象
}
// forin可以用于對(duì)象和數(shù)組的遍歷
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
result[key]=deepClone(obj[key]) // 使用遞歸
}
}
}
- 再次聲明測(cè)試
/**
* 深度克隆
* @param {object} obj 需要克隆的對(duì)象/數(shù)組
*/
function deepClone(obj={}){
console.log(obj)
//obj每次的值
//王 23 {city: "河南省鄭州市"} 河南省鄭州市 ["play", "eat"] play eat
if(typeof obj!=='object'||obj==null){
return obj
}
let result // 將要返回的變量
if(obj instanceof Array){
result=[] // 如果Obj為數(shù)組,則將返回定義為空數(shù)組
}else{
result={} // 如果Obj為對(duì)象担孔,則將返回定義為空對(duì)象
}
// forin可以用于對(duì)象和數(shù)組的遍歷
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
result[key]=deepClone(obj[key]) // 使用遞歸
}
}
return result
}
let obj2=deepClone(obj1)
obj2.name='李'
console.log(obj1.name,obj2.name) // 王 李
經(jīng)過(guò)手動(dòng)實(shí)現(xiàn)深度拷貝后就會(huì)發(fā)現(xiàn)江锨,當(dāng)改變obj2的值后,obj1并不會(huì)發(fā)生改變。