做爲面試必問的題目之一,看似簡單的問題,有不少細節有時候仍是很難注意到。此次對JS的深拷貝與淺拷貝作一個總結。面試
淺拷貝:拷貝對象第一層基本數據類型數據,如有子對象,則拷貝子對象地址,操做子對象時互有影響**數組
深拷貝:徹底拷貝對象,對兩個對象進行操做時互不影響**bash
基本數據類型(string,number,boolean,null,undifuned)函數
特性:原始值不可變,存放於棧中,當進行賦值操做時,生成的兩個變量互不干擾ui
引用數據類型(對象,函數組等)spa
特性:值可變,存放於堆中,當進行賦值操做時,拷貝的是引用地址,兩個地址指向同一對象,兩個變量對這個對象都可操做(深淺拷貝均針對引用數據類型)code
定義cdn
將對象的第一層基本數據類型值進行拷貝,當碰見子對象時拷貝其地址。當對拷貝對象的基本數據類型屬性值操做時,二者互不影響,而對拷貝對象的子對象進行操做時,原對象的子對象也會發生變化對象
實現blog
function shallowCopy(obj){
let des={}
for(let i in obj){
if(obj.hasOwnProperty(obj[i])){ //去除原型鏈屬性
des[i]=obj[i]
}
}
return des
}
複製代碼
基本數據類型進行了值拷貝,而對象則拷貝了地址
let des = Object.assign({},obj)
複製代碼
拷貝目標對象全部可枚舉屬性,但爲淺拷貝
let des = arr.slice()
複製代碼
對數組進行拷貝,但爲淺拷貝
let des = arr.concat()
複製代碼
同上
定義
徹底拷貝目標對象,不管怎麼操做拷貝對象,目標對象均不變化。二者互不影響
實現
遞歸拷貝
function isObj(obj){
return (typeof obj === 'object' || typeof obj === 'function') && obj != null
}
function deepClone(obj){
let des=Array.isArray(obj)?[]:{}
for(let i in obj){
des[i]=isObj(obj[i])?deepClone(obj[i]):obj[i]
}
return des
}
let a = {
name:'hkj',
obj:{
age:30
},
b:undefined,
c:Symbol(11),
arr:[1,2,3],
time:new Date(),
reg:/\d/,
fun:()=>{return}
}
let b=deepClone(a)
console.log(a)
console.log(b)
複製代碼
let a = {
name:'hkj',
obj:{
age:30
},
b:undefined,
c:Symbol(11),
arr:[1,2,3],
time:new Date(),
reg:/\d/,
fun:()=>{return}
}
let b=JSON.parse(JSON.stringify(a))
console.log(a)
console.log(b)
複製代碼