1、深拷贝和浅拷贝的区别:
简单来说深拷贝是拷贝储存在内存堆中的对象,而浅拷贝是从内存栈中拷贝。
数据分为两种数据类型,一种是基本数据类型,单独可以存在内存中就可以,而另一种是复杂数据类型,也叫引用数据类型,例如数组和对象,是放在内存堆中存储的。
基本数据类型是放在内存栈中的,不涉及深拷贝和浅拷贝,也可以说基本数据类型的拷贝都是深拷贝。而引类型数据存储比较复杂,是存放在到内存堆当中,将地址存在内存栈当中,这就构成了一个存储关系。浅拷贝简单来说就是把这份地址复制了一份,但内存堆当中的数据并没有复制,两个对象指向的是同一个数据,所以修改一个会影响另一个。而深拷贝就是,真真正正的复制了一份数据,放到了内存堆当中一个新的地址空间,并在内存栈中存放了新地址,拷贝前后的两个对象没有关联,不会互相影响。
2、递归函数
这种方法通过递归调用函数的方式来实现对象的深拷贝,很常用,几乎没有缺陷,就是代码量稍多,推荐!
var deepCopy = function(obj) {
// 如果不是对象类型数据 则返回该数据
if(typeof obj !=='object')
return obj
// 判断是对象还是数组
var newObj = obj instanceof Array?[]:{}
// 利用for...in.. 开始遍历对象的属性名
for(var key in obj) {
// hasOwnProperty 用来判断属性是否属于对象本身
// 只遍历对象本身的属性,跳过从原型链继承的属性
if(obj.hasOwnProperty(key)) {
// 如果是对象类别的数据类型,就递归调用 进行拷贝
// 如果是简单数据类型 就直接复制
newObj[key] = typeof obj[key] === 'object'?deepCopy(obj[key]):obj[key]
}
}
// 返回最后的深拷贝的对象
return newObj
}
3、JSON.parse() + JSON.Stringify()
该方法是通过将对象转化为 json 字符串,复制一份,最后再转换为对象的方式,实现深拷贝。优点很明显,代码很简单。但是有较大缺陷:会忽视 function、symbol 和 undefined 的字段,对 date类型的支持也不太友好,慎用!
var jsonClone = function (obj) {
return JSON.parse(JSON.stringify(obj));
}
4、jQuery 的 $.extend()
该方法是 jQuery的内置方法,即可进行深拷贝,也能浅拷贝。优点在于简单,缺点在于必须依赖jQuery。
// 第一个参数不传(false是不能够显示的写出来的)默认为false,是浅拷贝。传true为深拷贝。
// $.extend(true,object1, object2)
// newObject 即为深拷贝出来的对象
var newObject = $.extend(true , {} , object);
5、浅拷贝的两种方法
① Object.assign
var ObjA = Object.assign({}, obj)
② Object.create
var ObjA = Object.create(obj)
③ 直接赋值
var ObjA = obj