JavaScript深拷貝淺拷貝全析
阿新 • • 發佈:2020-07-31
淺拷貝
用淺拷貝如果改變obj2的物件,obj1不會再改變,它們不會引用一個值,但如果物件裡面還有物件,就會失效,它們是同一個引用。
方法1:用Object.create克隆物件
方法2:陣列用concat
方法3:物件用assign
方法4:擴充套件運算子(...)
方法1:用Object.create克隆物件
用法:
var obj1 = {a:2,b:{name:'小明'}};
var obj2 = Object.create(obj1);
詳解:
var obj1 = {a:2,b:{name:'小明'}}; var obj2 = Object.create(obj1); obj2.a = 3; obj2.b.name = '小紅'; console.log(obj1,obj2);
結果:
結論:
obj1物件中的一級物件a:2並沒有受影響,但二級物件b已經受影響。所以Object.create克隆的物件也只能實現一級物件的深拷貝。
方法2:陣列用concat
用法:
[].concat(arr)
詳解:
var arr = [{id:1,name:'1',other:{sex:'男'}}]
var brr = [].concat(arr);
brr[0].id = 2;
brr[0].other.sex = '女';
console.log(arr[0],brr[0])
結果:
結論:
arr的一級物件(id)和物件裡面的物件(other.sex)都是引用同一個指標,不能實現深拷貝。
方法3:物件用assign
用法:
var obj1 = {a: 1}
var obj2 = Object.assign({}, obj1)
詳解:
var obj = {id:1,name:{a:'xx'},fn:function(){},un:undefined};
var obj2 = Object.assign({}, obj);
obj2.id = 2;
obj2.name.a = 'obj2';
console.log(obj,obj2)
結果:
結論:
obj的一級物件(id)的確不受影響,但物件裡面的物件(name.a)還是引用同一個指標,不能實現深拷貝。
方法4:擴充套件運算子(...)
用法:
var obj1 = {a: 1}
var obj2 = {...obj1}
詳解:
var obj = {id:1,name:{a:'xx'},fn:function(){},un:undefined};
var obj2 = {...obj};
obj2.id = 2;
obj2.name.a = 'obj2';
console.log(obj,obj2)
結果:
結論:
obj的一級物件(id)的確不受影響,但物件裡面的物件(name.a)還是引用同一個指標,不能實現深拷貝。
深拷貝
方法1:JSON.parse(JSON.stringify())
方法2:MessageChannel
方法3:lodash.cloneDeep
用深拷貝的話,就算物件裡面還有物件,也不會是同一個引用,但是會忽略undefined
和function
,用方法3不會忽略function
和undefined
。
方法1:JSON.parse(JSON.stringify())
var obj1 = {a: 1}
obj2 = JSON.parse(JSON.stringify(obj1))
方法2:MessageChannel
var obj = {id:1,name:{a:'xx'}};
function structuralClone(obj) {
return new Promise((resolve) => {
const {port1, port2} = new MessageChannel();
port2.onmessage = ev => resolve(ev.data);
port1.postMessage(obj);
})
}
structuralClone(obj).then(res=>{
console.log(res);
var obj3 = res;
obj3.name.a = 'obj3';
console.log(obj,obj3);
})
<!-- 用promise是為了好傳資料 -->
方法3:lodash.cloneDeep
import _ from 'lodash'
var obj = {id:1,name:{a:'xx'},fn:function(){},un:undefined};
var obj2 = _.cloneDeep(obj);
obj2.name.a = 'obj2';
console.log(obj,obj2)