ES6学习笔记--浅拷贝深拷贝
为什么有浅拷贝深拷贝一说:
基本数据:直接存储在栈(stack)中的数据
引用数据:存储的是该对象在栈中引用,真实的数据存放在堆内存里
浅拷贝方法:
1.Object.assign({},obj) 用于对象与数组
var obj = { a: {a: "kobe", b: 39} };
var initalObj = Object.assign({}, obj);
initalObj.a.a = "wade";
console.log(obj.a.a); //wade复制代码
2.arr.concat() 用于数组
let arr = [1, 3, {
username: 'kobe'
}];
let arr2=arr.concat();
arr2[2].username = 'wade';
console.log(arr);复制代码
3.arr.slice() 用于数组
let arr = [1, 3, {
username: ' kobe'
}];
let arr3 = arr.slice();
arr3[2].username = 'wade'
console.log(arr);复制代码
4.let obj1={...obj} 用于对象与数组
深拷贝方法:
1.JSON.parse(JSON.stringify(obj))
最简单的方式,但是有一些缺陷
- 对象的属性值是函数时,无法拷贝。
- 原型链上的属性无法拷贝
- 不能正确的处理 Date 类型的数据
- 不能处理 RegExp
- 会忽略 symbol
- 会忽略 undefined
2.手撕DeepClone函数
function deepClone(obj,hash=new WeakMap()){
if(obj instanceof RegExp) return new RegExp(obj) //正则表达式 则返回
if(obj instanceof Date) return new Date(obj) //时间格式 则返回
if(obj ===null|| typeof obj!='object'){ //基本类型和null类型,函数类型 则返回
return obj
}
//能进行到下面说明是数组,对象
if(hash.has(obj)){ //查询哈希表,有循环引用时,直接从哈希表中取出对象
return hash.get(obj)
}
let t=new obj.constructor() //obj为要复制的对象,t为自己创建的对象,用来创建一份和obj一样但不关联的对象
hash.set(obj,t) //把对象存入哈希标,以防循环引用
for(let key in obj){ //遍历obj中每个属性
if(obj.hasOwnProperty(key)){
t[key]=deepClone(obj[key],hash)
}
}
return t
}复制代码