js的深拷贝和浅拷贝

区别

  • 浅拷贝(shallow copy):只复制指向对象的指针,而不复制对象本身,新旧对象是共享一块内存的,一个对象改变,另一个也会改变
  • 深拷贝(deep copy):复制并创建一个一样的对象,不会共享内存,两个对象互不相干

深拷贝和浅拷贝也是针对引用类型(Object、Array)而言的;而像基本类型,它们在栈内存中占据着固定大小的空间,一个变量复制另一个变量,只会创建这个值的副本(值相等),两个变量却互不影响,当然基本数据类型是不能添加属性的

var a = 1;
var b = a;
a = 2;
a.name ='a';
console.log(a); //2
console.log(b); //1
console.log(a.name); //undefined

浅拷贝的实现

平常用 = 赋值操作符赋值,就是浅拷贝,只复制了对象的引用指针

var obj1 = { "name":"xqq"}
var obj2 = obj1;
obj1.name = "oop";
console.log(obj1.name); // "oop"
console.log(obj2.name); // "oop"

深拷贝的实现

1.数组的深拷贝:slice()、concat(),但是这两个方法仅适用于对不包含引用对象的一维数组的深拷贝

var arr1 = [ 'a','b','c']
var copy1 = arr1.slice(0);
copy1[0] = 'd';
console.log(arr1); //['a','b','c']
console.log(copy1); //['d','b','c']

var arr2 = [ {name:"xiaoming"},{name:"laozhang"}];
var copy2 = [].concat(arr2);
arr2[0].name ="feifei";
console.log(arr2); //[ {name:"feifei"},{name:"laozhang"}];
console.log(copy2); //[ {name:"feifei"},{name:"laozhang"}];

数组的深拷贝也可以借助ES6的扩展运算符实现

var arr = [1,2,3]
var [ ...arr2 ] = arr
arr[0] = 5
console.log(arr)  //[5,2,3]
console.log(arr2)  //[1,2,3]

2.对象的深拷贝:

  • ES6扩展运算符来实现
  • 递归实现每一层重新创建对象并赋值
  • json的parse和stringify
var obj ={
  name:'jack',
   age:15
}
var { ...copy }  = obj
obj.age = 18
console.log(obj)  // { name:'jack',age:18}
console.log(copy)  //{name:'jack',age:15}

递归的方法就是每一层的数据都实现一次 创建对象 -> 对象赋值的过程

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;
}

你可能感兴趣的:(web前端)