JS物件的引用,物件的拷貝
阿新 • • 發佈:2018-12-28
一、場景
除了基本型別跟null,物件之間的賦值,只是將地址指向同一個,而不是真正意義上的拷貝
將一個物件賦值給另外一個物件。
var a = [1,2,3];
var b = a;
b.push(4); // b中添加了一個4
alert(a); // a變成了[1,2,3,4]
自定義物件
var obj = {a:10};
var obj2 = obj;
obj2.a = 20; // obj2.a改變了,
alert(obj.a); // 20,obj的a跟著改變
這就是由於物件型別直接賦值,只是將引用指向同一個地址,導致修改了obj會導致obj2也被修改
二、淺拷貝
所以,我們需要封裝一個函式,來對物件進行拷貝,通過for in 迴圈獲取基本型別,賦值每一個基本型別,才能真正意義上的複製一個物件
var obj = {a:10};
function copy(obj){
var newobj = {};
for ( var attr in obj) {
newobj[attr] = obj[attr];
}
return newobj;
}
var obj2 = copy(obj);
obj2.a = 20;
alert(obj.a); //10
這樣就解決了物件賦值的問題。
三、深拷貝
但是這裡存在隱患,如果obj中,a的值不是10,而是一個物件,這樣就會導致在for in中,將a這個物件的引用賦值為新物件,導致存在物件引用的問題。
var obj = {a:{b:10}};
function copy(obj){
var newobj = {};
for ( var attr in obj) {
newobj[attr] = obj[attr];
}
return newobj;
}
var obj2 = copy(obj);
obj2.a.b = 20;
alert(obj.a.b); //20
因此,由於這個copy物件只是對第一層進行拷貝,無法拷貝深層的物件,這個copy為淺拷貝,我們需要通過遞迴,來拷貝深層的物件。將copy改造成遞迴即可
var obj = {a:{b:10}}; function deepCopy(obj){ if(typeof obj != 'object'){ return obj; } var newobj = {}; for ( var attr in obj) { newobj[attr] = deepCopy(obj[attr]); } return newobj; } var obj2 = deepCopy(obj); obj2.a.b = 20; alert(obj.a.b); //10 //當然利用 Object.assign 也能解決
2. JSON物件形式亦闊以處理
let params = JSON.parse(JSON.stringify(this.form));
3.es6 的 Object.assign
let obj = {a:1,b:2},obj2={}
Object.assign(obj2,obj)
console.log(obj2) // {a:1,b:2}
console.log(obj2 == obj) // false
//Object.assign 只能做淺拷貝之用 也就是說 只能拷貝一層
4.es6 的解構方法
let obj = {a:1,b:2}
let obj1 = {...obj}
console.log(obj1) // {a:1,b:2}
console.log(obj == obj1) //false
let aa = {a:1,b:{c:11}}
let bb = {...aa}
bb.b.c = 22
console.log(aa.b.c) // 22
console.log(bb) // {a:1,b:{c:22}}
console.log(aa == bb) // false
//也只能拷貝一層之用