在js中,如果乙個物件,作為變數賦值給另乙個物件,那麼兩個物件得值會是相同得引用位址,其中乙個改變,另外乙個也會隨之改變。
var obj1 =
var obj2 = obj1;
obj2.num = 456;
console.log(obj1.num); // 輸出: 456
複製**
` 在我們日常開發過程當中,我們去複製乙個物件得目的是為了去獲得該物件的值,我們對獲得的值進行操作,不會影響原物件才對。而我們要解決這樣的問題,就涉及到了使用物件的淺拷貝和深拷貝來解決問題了。
淺拷貝是我們日常開發使用最多的,因為他能解決我們日常開發中絕大部分的問題,首先最常用的方法就是:object.assign()
,是es6:object裡的新增方法,object.assign()
方法用於物件的合併,將源物件(source)的所有可列舉屬性,複製到目標物件(target),那麼如何使用呢,請看案例:
var obj1 =
var obj2 = object.assign({}, obj1);
obj2.num = 456;
console.log(obj1.num, obj2.num); // 輸出: 123 456
複製**
使用方法,還是非常簡單的,我們也可以使用擴充套件運算子...
的方法來實現淺拷貝: `
var obj1 =
var obj2 = ;
obj2.num = 456;
console.log(obj1.num, obj2.num); // 輸出: 123 456
複製**
`所謂淺拷貝,實際上指的就是複製物件本身可列舉的屬性,不會拷貝到繼承屬性和可本身可列舉屬性的值也是物件裡的值。
上面那句話的後半段裡看上去有點繞,這裡在講什麼是深拷貝,你就立馬理解了。而深這個字我個人覺得就挺通俗易懂了,說白了就是更深層次的拷貝唄。那麼怎麼就是深拷貝呢?看案例: `
var obj1 =
}var obj2 = object.assign({}, obj1);
obj2.child.str = '子物件的str值';
console.log(obj1.child.str); // 輸出: 子物件的str值
複製**
通過上面的案例,我們發現,我們用了淺拷貝,但是obj1
和obj2
裡面的child
子物件還是共用了乙個引用位址,這就是我上面說的那句「本身可列舉屬性裡的值也是物件」,所以我們就需要更深層次的拷貝到這個物件裡來唄,這就需要使用深拷貝了,最常見的深拷貝方法就是:json.parse(json.stringify(obj1))
,下面看案例:
var obj1 =
}var obj2 = json.parse(json.stringify(obj1));
obj2.child.str = '子物件的str值';
console.log(obj1.child.str); // 輸出: 子級物件
複製**
通過使用json.parse(json.stringify(obj1))
我們實現了深拷貝,其實該方法的實現原理非常的簡單,json.stringify()
是把我們的物件轉換成了json字串,字串屬於基本型別了,已經不存在引用位址了,然後我們在用json,pase()
把它轉換回來,此時它已經是乙個新物件了,和原物件沒有任何關係了。通過這樣轉換的方式實現了深拷貝。但是呢,該方法也存在一定的侷限性,或者說是不足:
下面看案例:
let obj = ,
}obj.c = obj.b
obj.e = obj.a
obj.b.c = obj.c
obj.b.d = obj.b
obj.b.e = obj.b.c
let newobj = json.parse(json.stringify(obj))
console.log(newobj)
複製**
如果你的物件像這樣的相互引用賦值的話,那麼你會發現不能使用json.parse(json.stringify(obj1))
來實現了,並且還報錯:
不僅如此,在遇到undefined
和函式時,也不能正常實現深拷貝:
let obj1 = ,
tel: 13880089009
}let obj2 = json.parse(json.stringify(obj1))
console.log(obj2) //
複製**
這樣只拷貝到了tel
乙個屬性值:那麼這個時候就會用到常用得另一種深拷貝方式了:for in
let obj1 = ,
tel: 13880089009
}let obj2 = {}
for (let key in obj1)
console.log(obj2) //
複製**
for in
本身是乙個比較耗效能得迴圈方法,它實現得方式也簡單粗暴,就是乙個屬性乙個屬性得賦值,for in
還可以遍歷到物件繼承得所有屬性和方法,正是因為這一點,所以for in
是個耗效能得主。
本篇章主要講解得是淺拷貝和深拷貝這樣得乙個概念,並給出了個人用得一些淺拷貝和深拷貝得方法,用於對我們日常開發當中注意得一些細節操作。喜歡得朋友給個贊吧,謝謝。
js 物件深拷貝 深拷貝與淺拷貝
前言 最近在複習一些面試的知識點,剛剛好複習到了這一部分,於是就寫下這篇文章記錄一下。一 值型別和引用型別 在學習深拷貝和淺拷貝之前,我們先來了解一下js的變數型別。值型別 vs 引用型別 值型別 值型別主要有 number,string,boolean,symbol,null,undefined ...
JS 物件的深拷貝與淺拷貝
基本型別和引用型別 物件的深拷貝和淺拷貝 基本型別和引用型別 js中包含兩種資料型別,既基本型別和引用型別,基本型別是簡單的資料段,它是按值訪問的,因為基本型別可以操作儲存在變數中的值。而引用型別指的是那些可能由多個值構成的物件。引用型別的值是儲存在記憶體中的物件,在js中,規定不能直接訪問記憶體中...
js深拷貝與淺拷貝
1 基礎知識 基本型別與引用型別 js中可以把變數分成兩部分,基本型別和引用型別。基本型別包括 undefined null boolean number和string 引用型別值可能由多個值構成的物件。在對基礎型別資料進行拷貝時,實際相當於建立新的相同資料 hello 賦值給b var a hel...