解读经典面试题的深拷贝和浅拷贝
2019-02-12 16:45 WEB前端小菜鸟 阅读(3938) 评论(0) 编辑 收藏 举报以前我理解的浅拷贝就是赋值,深拷贝就是赋址,其实这么理解是错误的
对于基本类型来说浅拷贝就是赋值,
对于引用类型来说(obj,arr等),浅复制是对对象地址的复制,并没有开辟新的栈,也就是复制的结果是两个对象指向同一个地址,修改其中一个对象的属性,则另一个对象的属性也会改变,而深复制则是开辟新的栈,两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性
说白了就是浅拷贝都是相同的内存地址,你的值变了 我也跟到变,
深拷贝呢就是你变你的,我们地址都不一样的,你变了关我屁事
深复制实现代码如下:
可以从两个方法进行解决。
https://www.zhihu.com/question/23031215
第二条评论
componentDidMount(){ /* let a={age:25} let b=a b.age=30 console.log(a);//30 浅拷贝 只是复制的地址 指向的都是同一个内存地址,b改变,a也跟着改变 */ // 深拷贝(拷贝的对象属性值里面没有引用类型(对象等等)) /* let a={ age:25 } let b=Object.assign({},a) b.age=27 console.log(b,'222222')//27 console.log(a,'aaaa')//25 */ // 这样一看对的噢可以实现深拷贝,但是如果a对象中属性值是对象的话,拷贝的是地址,Object.assign所以并不是深拷贝。 /* let a={ age:25, status:{ name:'大哥' } } let b=Object.assign({},a) b.age=27 b.status.name='小弟' console.log(b,'222222')//27,name打印是小弟 console.log(a,'aaaa')//25,name打印是小弟 */ // 深拷贝 实现方式的话常用的两种JSON.parse(JSON.stringify(object)),该方法也是有局限性的 let a = { age:25, status:{ name:'大哥' } } let b = JSON.parse(JSON.stringify(a)) a.status.name = '小弟' console.log(b.status.name) // '大哥' console.log(a.status.name) // '小弟' // 方法二 lodash 的深拷贝函数 }
还有一种实现深拷贝的方法 就是 lodash里面的
_.cloneDeep
还有就是自己写的函数实现深度拷贝,改变原型
Object.prototype.clone = function() { // Handle null or undefined or function if (null == this || "object" != typeof this) return this; // Handle the 3 simple types, Number and String and Boolean if(this instanceof Number || this instanceof String || this instanceof Boolean) return this.valueOf(); // Handle Date if (this instanceof Date) { var copy = new Date(); copy.setTime(this.getTime()); return copy; } // Handle Array or Object if (this instanceof Object || this instanceof Array) { var copy = (this instanceof Array)?[]:{}; for (var attr in this) { if (this.hasOwnProperty(attr)) copy[attr] = this[attr]?this[attr].clone():this[attr]; } return copy; } throw new Error("Unable to clone obj! Its type isn't supported."); } let a={ name:'大哥', age:{ ages:27 } } let b=a.clone() b.name='小弟' console.log(a,'333')//大哥 console.log(b,'333')//小弟
还可以自己写一个函数,适用于大部分对象的深度复制(Deep Clone)。
function clone(obj) { // Handle the 3 simple types, and null or undefined or function if (null == obj || "object" != typeof obj) return obj; // Handle Date if (obj instanceof Date) { var copy = new Date(); copy.setTime(obj.getTime()); return copy; } // Handle Array or Object if (obj instanceof Array | obj instanceof Object) { var copy = (obj instanceof Array)?[]:{}; for (var attr in obj) { if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]); } return copy; } throw new Error("Unable to clone obj! Its type isn't supported."); } let a = { age:25, status:{ name:'大哥' } } let b = clone(a) a.status.name = '小弟' console.log(b) // '大哥' console.log(a) // '小弟'