想要克隆一个对象或者数组,假如只是普通的赋值,那么只是复制了浅层,深层的引用值其实指向的是同一块内存。
JSON克隆法
第一次看到这种克隆方法,把我惊呆了,还能这样克隆?
function JSONDeepClone(origin) { return JSON.parse(JSON.stringify(origin));}但这个方法也有缺点,当对象中包含【Function函数、Date日期对象、RegExp正则对象】时,克隆出的对象无法复制这些属性。
递归克隆
再很久以前学基础js的时候,就自己试着写了一下递归深度克隆,能深度克隆数组和对象。
function deepClone(origin) { let target; // 判断传入的origin的类型 if (getType(origin) == '[object Object]') { target = {}; }else if (getType(origin) == '[object Array]') { target = []; }else{ return origin; } // 遍历值,for-in可以遍历数组、对象 for(const key in origin){ // 假如值是数组或者对象,递归继续克隆 if (getType(origin[key]) == '[object Object]' || getType(origin[key]) == '[object Array]') { target[key] = deepClone(origin[key]); } //假如不是,直接赋值 else{ target[key] = origin[key]; } } return target;}// 判断类型function getType(sth) { return Object.prototype.toString.call(sth);}当然,这里还有缺陷。克隆出来的对象,函数、日期对象、正则对象等其实也是同一个引用。
对于处理日期对象,可以使用这种方法(同时在遍历值的时候,能否继续递归克隆的条件判断要多加上Date)
if (getType(origin) == '[object Date]') { return new Date(origin.getTime());}对于正则也是同样的思路,假如是[object RegExp],就new RegExp,用正则的少量属性获取被克隆的正则对象的信息