在写js的时候经常会遇到复制对象,在复制对象的过程中往往会出现新对象改变原对象等等的一些问题,今天特意梳理一下,希望能帮助到遇到这些问题的开发人员。
什么是浅拷贝,深拷贝以及和他们之间的区别 赋值 浅拷贝 深拷贝 在开始梳理之前先说一下值类型和引用类型: 值类型(基本类型):字符串(string)、数值(number)、布尔值(boolean)、undefined、null ; 引用类型:对象(Object)、数组(Array)、函数(Function);
1、什么是浅拷贝,深拷贝以及和他们之间的区别 浅拷贝是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 。 深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象。 区别:浅拷贝基本类型之前互不影响,引用类型其中一个对象改变了地址,就会影响另一个对象;深拷贝 改变新对象不会影响原对象,他们之前互不影响。 2、赋值 //对象赋值 let obj1 = { name: '张三', action: { say: 'hi'}; let obj2 = obj1; obj2.name = '李四'; obj2.action.say = 'hello' console.log('obj1',obj1) // obj1 { name: '李四', action: { say: 'hello'} console.log('obj2',obj2) // obj2 { name: '李四', action: { say: 'hello'} 1 2 3 4 5 6 7 8 9 3、浅拷贝 原数据中包含子对象,改变新对象会使原数据一同改变
Object.assign() //浅拷贝 let obj1 = { name: '张三', action: { say: 'hi'}; let obj2 = Object.assign({}, obj1); obj2.name = '李四'; obj2.action.say = 'hello' console.log('obj1',obj1) // obj1 { name: '张三', action: { say: 'hello'} console.log('obj2',obj2) // obj2 { name: '李四', action: { say: 'hello'} 1 2 3 4 5 6 7 8 9 展开运算符… 展开运算符是一个 es6特性,它提供了一种非常方便的方式来执行浅拷贝,这与 Object.assign ()的功能相同。 //浅拷贝 let obj1 = { name: '张三', action: { say: 'hi'}; let obj2 = {... obj1}; obj2.name = '李四'; obj2.action.say = 'hello' console.log('obj1',obj1) // obj1 { name: '张三', action: { say: 'hello'} console.log('obj2',obj2) // obj2 { name: '李四', action: { say: 'hello'} 1 2 3 4 5 6 7 8 9 注:concat(),slice()也属于浅拷贝
4、深拷贝 JSON.parse(JSON.stringify()) //深拷贝 let obj1 = { name: '张三', action: { say: 'hi'}; let obj2 = JSON.parse(JSON.stringify(obj1)); obj2.name = '李四'; obj2.action.say = 'hello' console.log('obj1',obj1) // obj1 { name: '张三', action: { say: 'hi'} console.log('obj2',obj2) // obj2 { name: '李四', action: { say: 'hello'} 1 2 3 4 5 6 7 8 9 jQuery.extend() $.extend(deepCopy, target, object1, [objectN])//第一个参数为true,就是深拷贝 //深拷贝 let obj1 = { name: '张三', action: { say: 'hi'}; let obj2 = $.extend(true, {}, obj1); obj2.name = '李四'; obj2.action.say = 'hello' console.log('obj1',obj1) // obj1 { name: '张三', action: { say: 'hi'} console.log('obj2',obj2) // obj2 { name: '李四', action: { say: 'hello'}