浅拷贝和深拷贝的解读
- 什么是浅拷贝,深拷贝以及和他们之间的区别
- 赋值
- 浅拷贝
- 深拷贝
在开始梳理之前先说一下值类型和引用类型:
值类型(基本类型):字符串(string)、数值(number)、布尔值(boolean)、undefined、null
引用类型:对象(Object)、数组(Array)、函数(Function)、正则、date..;
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'}
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'}
展开运算符…
展开运算符是一个 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'}
注:数组的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'}
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'}