js实现对象或者数组深拷贝
今天遇到个问题,就是vue绑定的数组在push中所有的数组都会跟着改变。这个主要是因为 JavaScript中对象或者数组等引用类型,直接拷贝,改变一个另外一个也会改变;
有个简单的方法就是先转换为字符串再转换为json
var arr = [1,2,3]; var arr1 = arr; arr1.push(4); console.log(arr); //[1,2,3,4] console.log(arr1);//[1,2,3,4]
上面这是没转换的.
1、通过JSON.stringfy()和JSON.parse()转换
var arr = [1,2,3]; var arr1 = JSON.stringify(arr); var arr2 = JSON.parse(arr1); arr2.push(4); console.log(arr); //[1, 2, 3] console.log(arr1);//字符串[1,2,3] console.log(arr2);//[1, 2, 3, 4]
这种方式也会有一下几点的不足:
1、会忽略 undefined
2、会忽略 symbol
3、不能序列化函数
4、不能解决循环引用的对象
5、不能正确处理new Date()
6、不能处理正则
2、通过递归
下面是简单的实现,更加完善的有Lodash这个库,能满足各种使用场景。
function deepCopy(obj) { if(typeof obj!='object'){ return obj } let newObj=obj instanceof Array ? []:{ }; for(let i in obj){ if(Object.prototype.hasOwnProperty.call(obj,i)){ type[i]=typeof obj[i]=='object' ? deep(obj[i]):obj[i] } } return newObj }
至于为什么要深拷贝,可以参考js 数据类型及检测