深拷贝
方案一:JSON序列化和解析
比较简单的深拷贝方案,但仅支持基本数据类型和部分引用数据类型
其不支持的类型或情况
- Symbol
- Function
- 循环引用(遇到此情况会报错)
const s1=Symbol()const obj={name:'rv',age:20,/* Function */running:()=>{console.log('running')},/* Symbol */[s1]:'symbol',symbol:s1/* Array */arr:[1,2,3,4]/* Object */friend:{ name:'why',age:18}}const copyObj=JSON.parse(JSON.stringify(obj));console.log(copyObj)/*Object{name: "rv"age: 20arr: (4) [1, 2, 3, 4]friend: {name: 'why', age: 18}}*/
方案二:手动实现深拷贝
function deepClone(originValue,map=new WeakMap()){/* Set、Map、WeakSet、WeakMap的拷贝处理 */if(originValue instanceof Set){return new Set([...originValue])}if(originValue instanceof Map){return new Map([...originValue])}if(originValue instanceof WeakSet||originValue instanceof WeakMap){return originValue}/* Symbol的拷贝处理 */if(typeof originValue==='symbol'){if(Symbol.keyFor(originValue)==null){return Symbol()}else{return originValue}}/* 基础数据类型和Function的拷贝处理 */if(!isObject(originValue)||typeof originValue==='function'){return originValue}/* 检测数组是否存在循环引用 */if(map.has(originValue)){return map.get(originValue)}/* 数组和普通对象的拷贝处理 */const newObject=Array.isArray(originValue)?[]:{}/* String key的拷贝处理 */for(const key in originValue){newObject[key]=deepClone(originValue[key],map)}/* Symbol key的拷贝处理 */const symbols=Object.getOwnPropertySymbols(originValue)for(const key of symbols){newObject[key]=deepClone(originValue[key],map)}map.set(originValue,newObject)return newObject}function isObject(value){const valueType=typeof valuereturn (value!==null)&&(valueType==='object'||valueType==='function')}
