常常會在一些網站或博客看到「深克隆」,「淺克隆」這兩個名詞,其實這個很好理解,今天咱們就在這裏分析一下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
。指針
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
等,這裏就不深究。code