javascript的浅拷贝和深拷贝

深拷贝和浅拷贝简单解释

        浅拷贝和深拷贝都只针对于引用数据类型进行拷贝的,浅拷贝只复制指向某个对象的第一层,对于大于2层的,新旧对象还是共享同一块内存;但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,无论怎么修改新对象也不会影响原对象。

        区别:浅拷贝只复制对象的第一层属性、深拷贝可以对对象的属性进行递归复制

浅拷贝的实现

方式一:Object.assign()方式

    let obj1 = {
      name: 'zhangsan',
      age: 20,
      hobby: {
        like1: 'play basketball',
        like2: 'travel' 
      }
    };
    let obj2 = Object.assign({}, obj1);
    // 更改第一层
    obj2.name = 'lisi';
    obj2.hobby.like1 = "reading"
    console.log(obj1, obj2)

 

方式二:用...的实现

    let obj1 = {
      name: 'zhangsan',
      age: 20,
      hobby: {
        like1: 'play basketball',
        like2: 'travel' 
      }
    };
    let obj2 = {
      ...obj1
    }
    // 更改第一层
    obj2.name = 'lisi';
    obj2.hobby.like1 = "reading"
    console.log(obj1, obj2)

结果依旧如上图。

 

深拷贝的实现

JavaScript原生的方式

方式一:使用JSON.stringify和JSON.parse实现深拷贝:JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象;

代码:

function deepCopy(obj){
  // 将引入的对象转化为字符串的形式
  let obj1 = JSON.stringify(obj)
  // 将obj1的字符串形式转化为对象
  let obj2 = JSON.parse(obj1)
  // 返回对象
  return obj2
}

// 测试
let page = {
  username: 'zhangsan',
  week: [1, 2, 3, [4, 5], 6]
}
// 开始深拷贝
let newPage = deepCopy(page)
newPage.username = 'lisi'
newPage.week[3][1] = 100

console.log('page', page) // 未变
console.log('newPage', newPage)// 变化 

看效果截图:

缺陷:它会抛弃对象的constructor,深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object;这种方法能正确处理的对象只有 Number, String, Boolean, Array, 扁平对象,也就是说,只有可以转成JSON格式的对象才可以这样用,像function没办法转成JSON;

方法二:递归实现深拷贝

代码:

function deepClone (obj) {
  // 判断是否未对象类型,并且对象不为空和underfined,如果是就直接返回对象
  if (typeof obj !== 'object' || obj == null) {
    // 返回obj并跳出deepClone,一般返回的都是属性值
    return obj
  }
  //初始化结果
  let result
  // instanceof使用用来判断引用类型中的数组和对象的
  if(obj instanceof Array){
    result = []
  } else {
    result = {}
  }

  // 对键值对的值做一个循环
  // 虽然说上面的obj已经跳出去了这个函数,但是这个循环还是在继续的,递归仍在继续
  for(let key in obj){
    // hasOwnProperty来判断obj有没有原生属性key
    if(obj.hasOwnProperty(key)){
      // 递归调用,
      //下面这种写法相当于result.key = deepClone(obj.key)的写法 
      result[key] = deepClone(obj[key]) 
    }
  }
  //返回结果
  return result
}

// 测试
const obj1 = {
  age: '11',
  username: 'qqq',
  city: {
    1: 'hangzhou',
    2: 'shanghai'
  },
  portman: ['a','e','i','o','u'],
  function () {
    console.log('我是函数')
  }
}

const obj2 = deepClone(obj1);
obj2.username='xx1x111111'
console.log('拷贝前obj1', obj1)
console.log('拷贝后obj2', obj2)

结果实现:


JQuery的方式

jquery 提供一个$.extend可以用来做深拷贝(具体代码不做演示);

备注:slice()和concat()都并非深拷贝;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值