JS对象的万能深拷贝的方法

JS 对象的深拷贝的方法

在js中我们的对象都是保存在堆中,当要使用的时候,通过栈中的指针去堆中找(指针寻址)

let obj={name:'zhangsan',age:18}
let copyObj=obj//此处拷贝只是复制了栈中指针,它和obj指向的是堆中同一个对象,当改变copyObj的属性,obj也会跟着变化,也就是我们说的浅拷贝
copyObj.name='lisi'
console.log(obj)//此处输出的结果{name:'lisi',age:18}

如何进行深拷贝?

1.常用的JSON.parse(JSON.stringify(obj))

此方法当属性中有函数和undefined,则序列化的的结果会把函数和undefined丢弃

  let obj = {
        name: "test",
        fun: function () {
          console.log("function");
        },
        old: undefined,
      };
      let result = JSON.parse(JSON.stringify(obj));
      console.log(result);//此处输出的结果:{name:'test'}
      //当你要深拷贝的对象中有函数和undefined要避免使用   

2.使用ES6扩展运算(只能拷贝一层)

   let obj = {
        name: "test",
        fun: function () {
          console.log("function");
        },
        old: undefined,
      };
      let copyObj = { ...obj };
      copyObj.name = "test1";
      console.log(obj);
   

在这里插入图片描述
当我们要深拷贝的对象里面还嵌套有对象的时候,此方法不能使用

   let obj = {
        name: "test",
        fun: function () {
          console.log("function");
        },
        old: undefined,
        obj: {
          name: "lisi",
          age: 19,
        },
      };
      let copyObj = { ...obj };
      copyObj.name = "test1";
      copyObj.obj.age = 88;
      console.log(obj);

在这里插入图片描述

3.使用ES6的 Object.assign()

此方法和扩展运算类似,只能深拷贝一层,这里就不举栗子了

4.万能深拷贝方法(可以拷贝数组和对象)

    let obj = {
        name: "test",
        fun: function () {
          console.log("function");
        },
        old: undefined,
        obj: {
          name: "lisi",
          age: 19,
        },
      };
      function isObject(obj) {
        let result =
          (typeof obj === "object" || typeof obj === "function") &&
          typeof obj != null;
        return result;
      }
      function deepCopy(obj) {
        if (!isObject(obj)) {
          throw Error("不是一个对象");
        }
        let isArray = Array.isArray(obj),
          copyObj = isArray ? [] : {}; //判断传入的obj是一个数组还是一个对象
        for (let key in obj) {
          copyObj[key] = isObject(obj[key]) ? deepCopy(obj[key]) : obj[key];
        }
        return copyObj;
      }
      let result = deepCopy(obj);
      result.obj.name = "zhangsan";
      console.log(obj);
      console.log(result);

在这里插入图片描述

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;
}
// 测试

var a = {
  name: '张三',
  skills: ['踢球', '跑步', '打羽毛球'],
  age: 18,
  love: {
    name: '小红',
    age: 16
  },
  map: new Map([['aaa', '123']]),
  fn:function(a){
    console.log(`我的名字叫${this.name}` + a)
  },
  set: new Set([1,2,3,4,5])
}
var newA = clone(a)
a.age = 100
a.love.age = 100
a.set.add('1123')
a.skills.push('计算机')
a.name = '小梅'
a.map.set('name', '小明')

console.log(a)
console.log(newA)

a.fn('a')
newA.fn('newA')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值