常常會在一些網站或博客看到「深克隆」,「淺克隆」這兩個名詞,其實這個很好理解,今天咱們就在這裏分析一下js深拷貝和淺拷貝
。javascript
咱們先以一個例子來講明js淺拷貝:java
var n = {a: 1, b: 2}
var m = n
m.a = 12
console.log(n.a) // ?
複製代碼
上面顯然 n.a
的值會變爲 12,這就是js淺拷貝。淺拷貝只是拷貝的指向對象的指針,本質上仍是指向同一個對象。正則表達式
一樣咱們仍是以一個例子來講明啥叫 js deep clone
:數據結構
var n = {a: 1, b: 2}
var m = {a: n.a, b: n.b}
m.a = 12
console.log(n.a) // ?
複製代碼
上面的輸出結果顯然仍是 1
,m 和 n 雖然全部的屬性和值所有相同,可是它們是兩個不一樣的對象,它們在堆內存中佔據兩塊不一樣的內存地址,這就是深度拷貝。深度拷貝就是徹底複製一個新的對象出來,它們在堆內存中徹底佔據兩個不一樣的內存地址。函數
上面的 深拷貝 例子網站
Object.assign()
方法const obj = {name: 'cc', age: 24}
const newObj = Object.assign({}, obj)
obj.name = 'cc1'
newObj.name ? // cc
複製代碼
JSON.parse(JSON.stringify(obj))
。缺點:它會對對於正則表達式類型、函數類型等沒法進行深拷貝,並且會直接丟失相應的值,還有就是它會拋棄對象的 constructor
。ui
var obj = { a: {a: "cc"}, b: 123 }
var newObj = JSON.parse(JSON.stringify(obj))
newObj.b = 1234
console.log(obj) // {a: {a: 'cc'}, b: 123}
console.log(newObj); // {a: {a: 'cc'}, b: 1234}
複製代碼
// 淺拷貝
var newObj = $.extend({}, obj)
// 深拷貝
var newObj = $.extend(true, {}, obj) // 要求第一個參數必須爲true
複製代碼
function deepClone(obj){
if(typeof obj !== "object" || obj === null) return
let newObj = obj instanceof Array ? [] : {}
for(let key in obj){
if(obj.hasOwnProperty(key)){
newObj[key] = typeof obj[key] === "object" && obj[key] !== null ? deepClone(obj[key]) : obj[key]
}
}
return newObj
}
let obj = {a: 1, b: function(){}, c: {d: 2}}
deepClone(obj) // {a: 1, b: function(){}, c: {d: 2}}
複製代碼
對於深拷貝來講最經常使用的就是這些方法,固然還有其餘的一些庫,好比 deepCopy
,lodash
等,這裏就不深究。spa