深拷贝
深拷贝
1.JSON.parse(JSON.stringify(data))
/** * 深拷贝 * @param data 传入数据,可为对象,也可为数组 * @returns String 返回 */ const copyVueData = (data) => { var newData = null; if (Object.prototype.toString.call(data) == "[object Object]") { newData = data ? JSON.parse(JSON.stringify(data)) : {}; } else if (Object.prototype.toString.call(data) == "[object Array]") { newData = data ? JSON.parse(JSON.stringify(data)) : []; } else if (Object.prototype.toString.call(data) == "[object String]") { newData = data ? JSON.parse(JSON.stringify(data)) : ''; } else if (Object.prototype.toString.call(data) == "[object Number]") { newData = data ? JSON.parse(JSON.stringify(data)) : null; } return newData; }
缺点:该方法不能解决属性为函数,undefined,循环引用的的情况

(1)原对象中的a、c不见了,undefined、function类型的key会丢失
(2)e时间对象,会变成字符串形式
(3)RegExp定义的属性会变成 {}
(4)NaN 类型会变成 null
(5)无法处理循环引用的问题
结论:这种拷贝方式局限性比较大,但是在日常开发中一般只是拷贝基本的数据类型,个人在开发中用的还是比较多
2.扩展运算符
利用了对象的结构赋值特性方法。
var arr = { name: '浪漫主义码农', age: 20, adress: ['jiangxi', 'changsha'], friends: { friend1: '张三', friend2: '李四' }, function(){ console.log("我是浪漫主义的对象") } } var brr={...arr} brr.name='法外狂徒张三' brr.adress[0]='长沙' console.log("arr为", arr) console.log("brr为", brr)
缺点:无对对象里面嵌套的对象进行深拷贝,相当于只是对一层引用对象进行深拷贝

3.递归深拷贝函数
通过递归实现深度拷贝,一般我们这样写
//使用递归实现深拷贝 function clone(obj) { //判断拷贝的obj是对象还是数组 var objClone = Array.isArray(obj) ? [] : {}; if (obj && typeof obj === "object") { //obj不能为空,并且是对象或者是数组 因为null也是object for (key in obj) { if (obj.hasOwnProperty(key)) { if (obj[key] && typeof obj[key] === "object") { //obj里面属性值不为空并且还是对象,进行深度拷贝 objClone[key] = clone(obj[key]); //递归进行深度的拷贝 } else { objClone[key] = obj[key]; //直接拷贝 } } } } return objClone; }
优化递归深拷贝
function checkType(any) { return Object.prototype.toString.call(any).slice(8, -1) } function clone(any){ if(checkType(any) === 'Object') { // 拷贝对象 let o = {}; for(let key in any) { o[key] = clone(any[key]) } return o; } else if(checkType(any) === 'Array') { // 拷贝数组 var arr = [] for(let i = 0,leng = any.length;i<leng;i++) { arr[i] = clone(any[i]) } return arr; } else if(checkType(any) === 'Function') { // 拷贝函数 return new Function('return '+any.toString()).call(this) } else if(checkType(any) === 'Date') { // 拷贝日期 return new Date(any.valueOf()) } else if(checkType(any) === 'RegExp') { // 拷贝正则 return new RegExp(any) } else if(checkType(any) === 'Map') { // 拷贝Map 集合 let m = new Map() any.forEach((v,k)=>{ m.set(k, clone(v)) }) return m } else if(checkType(any) === 'Set') { // 拷贝Set 集合 let s = new Set() for(let val of any.values()) { s.add(clone(val)) } return s } return any; }
结论:该方法可以解决深拷贝问题,但递归运行效率低,次数过多的话容易造成栈溢出。

浙公网安备 33010602011771号