面試時候有面試官問到ES6的解構賦值是深拷貝還是淺拷貝?,這裡做一個總結.
ES6的解構賦值,大家應該都清楚,就是可以快速取出數組或者對象中的值;我們先來看一個使用案例:
解構賦值
更多的解構賦值知識可以查看:
https://es6.ruanyifeng.com/#docs/destructuring
那麼,ES6的解構賦值到底是深拷貝還是淺拷貝呢?
我們先來看一下深拷貝和淺拷貝的定義
深拷貝:修改新變量的值不會影響原有變量的值。默認情況下基本數據類型(number,string,null,undefined,boolean)都是深拷貝。
淺拷貝:修改新變量的值會影響原有的變量的值。默認情況下引用類型(object)都是淺拷貝。
我們先開看一個基本類型,直接用等號賦值的例子
let user = 'siri'
let stu = user
stu = 'jack'
console.log('輸出:',stu)
// 輸出:jack
console.log('輸出:',user)
// 輸出:siri
由上方的例子可以知道:
stu的數值改變並不會影響user ,所以基本數據類型,直接用等號賦值,也都是深拷貝;
我們再看一個引用類型,直接用等號賦值的例子
let obj1 = {
name:'siri',
age:18
}
let obj2 = obj1
obj2.name = 'jack'
console.log('obj1',obj1)
console.log('obj2',obj2)
// obj1 {name: "jack", age: 18}
// obj2 {name: "jack", age: 18}

上方例子中我們可以看到,obj1賦值給obj2,然後改變obj2中的name值,發現obj2中的name也跟隨着改變了,所以是淺拷貝。(因為他們引用的是同一個地址的數據!拷貝的時候並沒有給obj2創造獨立的內存,只是把obj1指向數據的 指針 拷貝給了obj2)
上方的例子了解了之後 我們再回到解構賦值
修改最上方的解構賦值代碼,給name 和 age賦值
const userInfo = {
name:'siri',
age:18
}
let {name,age} = userInfo
name = 'jack'
age = 16
console.log('打印userInfo',userInfo)
// 打印userInfo {name: "siri", age: 18}
我們發現userInfo 的數據並沒有被改變,有同學會說,解構賦值好像是深拷貝啊?????
image.png
我們再修改一下代碼看看
const userInfo = {
name:'siri',
age:18,
detail:{
qq:'1',
email:'1366666@163.com'
}
}
let {name,age,detail} = userInfo
name = 'jack'
age = 16
detail.qq = "2"
console.log('打印userInfo',userInfo)
打印信息:

發現解構賦值出來的對象將原對象detail中的qq的數據修改了,這樣看還是淺拷貝;
總結:
- 解構賦值,如果所解構的原對象是一維數組或對象,其本質就是對基本數據類型進行等號賦值,那它就是深拷貝;
- 如果是多維數組或對象,其本質就是對引用類型數據進項等號賦值,那它就是淺拷貝;
結論:解構賦值是淺拷貝(因為它確實不能對多維數組或對象達到深拷貝的作用);
深拷貝的實現方法
本質還是將對象拆開為基本數據類型進行賦值。
function deepClone(source){
const targetObj = source.constructor === Array ? [] : {}; // 判斷複製的目標是數組還是對象
for(let keys in source){ // 遍歷目標
if(source.hasOwnProperty(keys)){
if(source[keys] && typeof source[keys] === 'object'){ // 如果值是對象,就遞歸一下
targetObj[keys] = source[keys].constructor === Array ? [] : {};
targetObj[keys] = deepClone(source[keys]);
}else{ // 如果不是,就直接賦值
targetObj[keys] = source[keys];
}
}
}
return targetObj;
}
原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/219448.html