js 对象和数组的浅拷贝和深拷贝
一、赋值、浅拷贝与深拷贝的区别
二、对象浅拷贝
第一种
对象的合并 Object.assign(),第一个参数必须是个空对象
var obj1 = {a: 1, b: 2}; var obj2 = Object.assign({}, obj1); obj1.a=100 console.log(obj1)//{a: 100, b: 2}; console.log(obj2)//{a: 1, b: 2};
第二种
对象的解构赋值
var obj1 = {a: 1, b: 2}; var obj2 = {...obj1}; obj1.a=100; console.log(obj1 )//{a: 100, b: 2}; console.log(obj2 )//{a: 1, b: 2};
第三种
利用数组的 slice 方法或者 concat 方法
var arr1 = ["aaa","bbb","ccc"]; var arr2 = arr1.slice(0); arr2[0] = "ddd"; console.log(arr1)//["aaa","bbb","ccc"] console.log(arr2)//["ddd","bbb","ccc"];
var arr1 = ["aaa","bbb","ccc"]; var arr2 = arr1.concat(); arr2[0] = "ddd"; console.log(arr1)// ["aaa","bbb","ccc"] console.log(arr1)// ["ddd","bbb","ccc"]
二、对象深拷贝
第一种
递归拷贝
function deepClone(source){ const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象 for(let keys in source){ // 遍历目标 if(source.hasOwnProperty(keys)){ if(source[keys] && typeof source[keys] === 'object'){ // 如果值是对象,就递归一下 targetObj[keys] = source[keys].constructor === Array ? [] : {}; targetObj[keys] = deepClone(source[keys]); }else{ // 如果不是,就直接赋值 targetObj[keys] = source[keys]; } } } return targetObj; }
第二种
... 拼接对象
let obj = { name: 'admin' } let obj2 = { age: 14, ...obj } console.log(obj2) // { age: 14, name: 'admin' }
第三种
利用jQuery的$.extend方法
//第一个参数不传(false是不能够显示的写出来的)默认为false,是浅拷贝。传true为深拷贝。 $.extend(true,object1, object2) //newObject 即为深拷贝出来的对象 var newObject = $.extend(true , {} , object);
第四种
用 JSON.stringify 把对象转换成字符串,再用 JSON.parse 把字符串转换成新的对象。可以转成 JSON 格式的对象才能使用这种方法,如果对象中包含 function 或 RegExp 这些就不能用这种方法了。
//通过js的内置对象JSON来进行数组对象的深拷贝 function deepClone(obj) { let _obj = JSON.stringify(obj); let objClone = JSON.parse(_obj); return objClone; }
第五种
lodash.cloneDeep()实现深拷贝,lodash是一个一致性、模块化、高性能的 JavaScript 实用工具库。
var objects = [{ 'a': 1 }, { 'b': 2 }]; var deep = _.cloneDeep(objects); console.log(deep[0] === objects[0]); // => false