本篇内容参考连结
原型基础物件导向
Roya's Blog
ZWE ZONE
Definition
上一篇了解到, call by value, reference 和 sharing 的区别后, 就可以开始探讨甚么是浅拷贝(shallow copy)和深拷贝. 还有为何会需要有这两种不同的拷贝.
Difference between Shallow and Deep
当我们再进行"複製"的动作时, 分为浅拷贝跟深拷贝
浅拷贝:只做浅层的複製, 记忆体的位址还是一样.深拷贝:
深度的複製物件, 原本物件与複製物件记忆体位址不相同, 操作新物件也不会影响原物件
所以当我们想要複製物件, 并使其不互相影响, 就会需要做深拷贝的动作了.
Shallow Copy Example
直接来参考範例
var originalObject = { a: "1", b: "2", c: "3" };var originalArray = ["1", "2", "3"];var orignialObjectInObject = { a: { content: "original" }, b: "2", c: "3" };var copyObject = Object.assign({}, originalObject);copyObject.a = "changed";var copyArray = Object.assign([], originalArray);copyArray[0] = "changed";var copyObjectInObject = Object.assign({}, orignialObjectInObject);copyObjectInObject.a.content = "updated";console.log(originalObject); // { a: "1", b: "2", c: "3" } -> 原物件不受影响console.log(copyObject); // { a: "changed", b: "2", c: "3" }console.log(originalArray); // ["1", "2", "3"] -> 原物件不受影响console.log(copyArray); // ["changed", "2", "3"]console.log(orignialObjectInObject); // { a: { content: 'updated' }, b: '2', c: '3' } -> 原物件受影响console.log(copyObjectInObject); // { a: { content: 'updated' }, b: '2', c: '3' }
乍看之下Object.assign()好像是deep clone, 事实上, Object.assign()仅是複製属性值, 若来源物件值也是一个物件(Object), 则只会複製其子物件的reference.
MDN: Object.assign()
使用 ES6 语法的 { … obj } 或是 Object.assign({}, obj) 都是不错的浅拷贝方式. 效能也相对比较好
Deep Copy Example
比较熟悉的应该就是 JSON.parse(JSON.stringify(obj)). 但效能相对比较不好.
var originalObject = { text: "Hello" };var copyObject;copyObject = JSON.parse(JSON.stringify(originalObject));copyObject.text = "Hi";console.log(originalObject); // { text: 'Hello' }console.log(copyObject); // { text: 'Hi' }
其他像是常见的 lodash 资料库的 cloneDeep方法, 效能稍微好一点. 或是利用递迴来每一个赋予值.