在 JavaScript 中栈存放的就是值类型的数据和引用类型的地址,而引用类型真正的数据被存放在堆中。
let obj={
name:'ut',
size:{width:70,heigh:180},
a: undefined,
fun: function rap() { },
advantage:['money'],
reg: /\d+/
}
对于引用(对象)类型来说,这种只是复制对象引用地址被称为浅拷贝(shallow copy),与之对应的,如果在堆中拷贝了一模一样的数据则被称为深拷贝(deep copy)。
方案一:Object.assign
Object.assign(obj);
缺陷:如果是多层的话 就是浅拷贝 一层就是深拷贝
方案2: JSON.parse(JSON.stringify(obj)
JSON.parse(JSON.stringify(obj);
缺陷:方法不能拷贝
方案3:解构赋值
缺陷:针对一维数组深拷贝,多维数组是浅拷贝
方案4:手写
function deepClone(value,hash = new WeakMap){ // 弱引用,不要用map
// null 和 undefiend 是不需要拷贝的
if(value == null){ return value;}
if(value instanceof RegExp){return new RegExp(value)}
if(value instanceof Date){return new Date(value)}
// 函数是不需要拷贝
if(typeof value != 'object') return value;
let obj = new value.constructor(); // [] {}
// 说明是一个对象类型
if(hash.get(value)){
return hash.get(value)
}
hash.set(value,obj);
for(let key in value){ // in 会遍历当前对象上的属性 和 __proto__指代的属性
// 补考呗 对象的__proto__上的属性
if(value.hasOwnProperty(key)){
// 如果值还有可能是对象 就继续拷贝
obj[key] = deepClone(value[key],hash);
}
}
return obj
// 区分对象和数组 Object.prototype.toString.call
}
let o = {};
o.x = o;
let o1 = deepClone(o); // 如果这个对象拷贝过了 就返回那个拷贝的结果就可以了
console.log(o1);