深拷贝和浅拷贝都只针对引用数据类型
深拷贝:拷贝多层,可以拷贝对象里的子对象
浅拷贝:不可以拷贝对象里的子对象。
深拷贝的实现:
1:原有的库函数
JSON.parse(JSON.stringfy(obj))
缺点:函数、正则、undefined 、无法拷贝
2.Object.assign(obj2,originalObj)
优点:可以拷贝函数、正则、undefinded可以拷贝,
缺点:深层次的拷贝是浅拷贝。
3.
var $ = require('jquery');
var obj2 = $.extend(true, {}, obj1); // 第一个参数为true,就是深拷贝
递归实现的深拷贝:
function deepClone(obj){
if(typeof obj!=='object'|| obj==null){
return obj;
}
let result;
if(obj instanceof Array){
result=[];
}else{
result={};
}
for(let key in obj){
if(obj.hasOwnProperty(key)){
result[key]=deepClone(obj[key]);
}
}
return result
}
循环引用:
循环引用指的是对象A 中包含一个指向对象B的指针,而对象B中也包含一个指向对象A的引用。
解决深拷贝因循环引用出现的无限循环问题;
function deepCopy(obj, map = new Map()) {
if (typeof obj !== 'object') return
let newObj = Array.isArray(obj) ? [] : {}
if (map.get(obj)) { // 如果对象曾经有过,就不用再深入循环拷贝了,返回
return map.get(obj)
}
map.set(obj, newObj) // 以对象为key,newObj是value
for (let key in obj) { // 遍历原型对象和实例中的属性
if (obj.hasOwnProperty(key)) { // 只需要深拷贝实例中的属性,原型上的属性在对象创建时就有
if (typeof obj[key] === 'object' && obj[key] !== null) {
newObj[key] = deepCopy(obj[key], map)
} else {
newObj[key] = obj[key]
}
}
}
return newObj
}