深拷贝浅拷贝

深拷贝浅拷贝

  1. 数据类型
// 按存储方式,js数据类型可以分为两大类:基本类型、引用类型
基本类型数据保存在在栈内存中
引用类型数据保存在堆内存中,引用数据类型的变量是一个指向堆内存中实际对象的引用,存在栈中
  1. 浅拷贝
// 如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址
function shollowclone(arg){
   if(typeof arg === 'object'){
       if(arg instanceof Array){
           let result = [];
           arg.forEach(item=>{
               result.push(item);
           })
           return result;
       }else{
           let result = {};
           const Keys = Object.keys(arg);
           for(let key of Keys){
               result[key] = arg[key];
           }
           return result;
       }
   }else{
       const result = arg;
       return result;
   }
}
const arr = [1,2,3,[1,2,3]];
const obj = {a:1,b:2,c:{one:1,two:2}};
let arr1 = shollowclone(arr);
let obj1 = shollowclone(obj);
arr1.push(4);
arr1[0] = 'one';
arr1[3].push(4)//arr 的数组也会被改变
obj1.c.one = 'once';// obj的c也会被改变
console.log(arr,arr1,obj,obj1);
// [1,2,3,[1,2,3,4]],["one",2,3,[1,2,3,4],4],{"a":1,"b":2,"c":{"one":"once","two":2}},{"a":1,"b":2,"c":{"one":"once","two":2}}

//在JavaScript中,存在浅拷贝的现象有:
//Object.assign   
//Array.prototype.slice(),
// Array.prototype.concat()    
//使用拓展运算符实现的复制
const obj = {a:1,b:2,c:{one:1,two:2}}
const obj1 = Object.assign({},obj);
const arr = [1,2,[1,2,3]];
let arr1 =[];
arr1 = arr1.concat(arr);
let arr2 = arr.slice(arr);
obj1.c.one = 'one';
arr1.push(4);
arr1[2].push(4);
arr1.push(4);
arr1[2].push(4);
console.log(obj,obj1,arr,arr1,arr2)
//{"a":1,"b":2,"c":{"one":"one","two":2}},{"a":1,"b":2,"c":{"one":"one","two":2}},[1,2,[1,2,3,4,4]],[1,2,[1,2,3,4,4],4,4],[1,2,[1,2,3,4,4]]

3.深拷贝

//深拷贝开辟一个新的栈,两个对象属性完成相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性
//常见的深拷贝方式有:
//_.cloneDeep() lodash
//jQuery.extend()
//JSON.stringify() 会忽略undefined、symbol和函数
//手写循环递归
function deepClone(obj, hash = new WeakMap()) {
  if (obj === null) return obj; // 如果是null或者undefined我就不进行拷贝操作
  if (obj instanceof Date) return new Date(obj);
  if (obj instanceof RegExp) return new RegExp(obj);
  // 可能是对象或者普通的值  如果是函数的话是不需要深拷贝
  if (typeof obj !== "object") return obj;
  // 是对象的话就要进行深拷贝
  if (hash.get(obj)) return hash.get(obj);
  let cloneObj = new obj.constructor();
  // 找到的是所属类原型上的constructor,而原型上的 constructor指向的是当前类本身
  hash.set(obj, cloneObj);
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      // 实现一个递归拷贝
      cloneObj[key] = deepClone(obj[key], hash);
    }
  }
  return cloneObj;
}
const arr =[1,2,3,4,[1,2,{a:1,b:2}]];
const arr1 = deepClone(arr,hash = new WeakMap());
arr1[4][2].a='one';
console.log(arr,arr1);// [1,2,3,4,[1,2,{"a":1,"b":2}]],[1,2,3,4,[1,2,{"a":"one","b":2}]]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值