js深拷貝初識
阿新 • • 發佈:2018-11-12
淺拷貝和深拷貝的區別
淺拷貝:只拷貝物件的基礎屬性值,對屬性值為物件或陣列的屬性則拷貝指標。
深拷貝:拷貝物件的所有屬性作為一個全新的物件。拷貝前後的物件互不影響。
淺拷貝
var a = {name:"test",children:{name:"test1"}} //淺拷貝 var b = { name:a.name, children:a.children } a.name = "字面量屬性拷貝" a.children.name = "淺拷貝" console.log(a)//Object {name: "字面量屬性拷貝", children: Object{name:"淺拷貝"}} console.log(b)//Object {name: "test", children: Object{name:"淺拷貝"}}
可以看出淺拷貝只拷貝了物件的基礎屬性值,對物件或陣列的屬性值則是隻是拷貝了引用。所以修改a.name的時候,由於name的屬性值為字串所以直接拷貝了,a的修改不影響b。當修改a.children屬性的時候,由於該屬性值是個物件,所以b只拷貝了引用,故b.children也變化了
深拷貝
var a = {name:"test",children:{name:"test1"}} //深拷貝 var b = { name:a.name, children:{name:a.children.name} } a.name = "字面量屬性拷貝" a.children.name = "淺拷貝" console.log(a)//Object {name: "字面量屬性拷貝", children: Object{name:"淺拷貝"}} console.log(b)//Object {name: "test", children: Object{name:"test1"}}
深拷貝是對淺拷貝的進一步解析,直到所有的屬性都為基礎屬性值為止,所以深拷貝的物件是完全獨立的一個新物件。
深拷貝公共方法封裝
/* ================ 深拷貝 ================ */ //返回傳遞給他的任意物件的類 const isClass = (o) => { if (o === null) return "Null"; if (o === undefined) return "Undefined"; return Object.prototype.toString.call(o).slice(8, -1); } //深度克隆 const deepClone = (obj) => { if (!obj) { return null } let result, oClass = isClass(obj); //確定result的型別 if (oClass === "Object") { result = {}; } else if (oClass === "Array") { result = []; } else { return obj; } for (let key in obj) { if (obj.hasOwnProperty(key)) { let copy = obj[key]; if (isClass(copy) == "Object") { result[key] = deepClone(copy);//遞迴呼叫 } else if (isClass(copy) == "Array") { result[key] = deepClone(copy); } else { result[key] = obj[key]; } } } return result; }
Object.assign()
特別注意:ES6提供了一個Object.assign()方法用於拷貝和合並物件,但是該方法也只是一個淺拷貝方法,使用時請慎重。