JS基础面试高频(三):浅拷贝和深拷贝

前言

工作中可能会遇到这样一个问题,我明明把数据拷贝了一份,但改变拷贝后的数据居然同时会改变原始数据中的值。那就来看看为什么吧,希望这篇文章可以给你解惑。

什么是浅拷贝?

只拷贝了数据对象的第一层,深层次的数据值与原始数据会互相影响(拷贝后的数据与原始数据还存有关联)


常见浅拷贝的方式: Object.assign()扩展运算符

const obj1 = { name: 'dog', info: { age: 3 } }
const obj2 = Object.assign({}, obj1)
// 或者
const obj2 = { ...obj1 }

obj2.name = 'cat'
obj2.info.age = 4
console.log(obj1) // { name: 'dog', info: { age: 4 } }
console.log(obj2) // { name: 'cat', info: { age: 4 } }

当拷贝后的对象obj2数据改变的时候会影响原始数据obj1,因为info对象拷贝的是源对象指针。

不清楚指针的可以看前面的这篇文章

JS基础面试高频(一):数据类型

什么是深拷贝?

不管数据对象有多少层,改变拷贝后的值都不会影响原始数据的值。(拷贝后的数据与原始数据毫无关系)

常见深拷贝的方式:JSON.parse()JSON.stringify()配合使用

const obj1 = { name: 'dog', info: { age: 3 }, fn: function () {} }
const obj2 = JSON.parse(JSON.stringify(obj1))
obj2.name = 'cat'
obj2.info.age = 4
console.log(obj1) // { name: 'dog', info: { age: 3 }, fn: function(){} }
console.log(obj2) // { name: 'cat', info: { age: 4 } }

这种方式有一个弊端,就是无法正确处理函数正则


我们也可以手写一个深拷贝的方法(简易基础版)

function deepClone(source) {
  // null数据需要特殊处理
  if (source === null) {
    return source
  }
  // 校验要拷贝的数据是对象还是数组
  const target = Array.isArray(source) ? [] : {}
  for (const k in source) {
    const val = source[k]
    const valueType = typeof val
    // 校验拷贝的数据类型
    if (valueType === 'function') {
      target[k] = new Function(`return ${val.toString()}`)()
    } else if (valueType === 'object') {
      target[k] = deepClone(val)
    } else {
      target[k] = val
    }
  }
  return target
}

const obj1 = { name: 'dog', info: { age: 3 }, fn: function () {} }
const obj2 = deepClone(obj1)
obj2.name = 'cat'
obj2.info.age = 4
console.log(obj1) // { name: 'dog', info: { age: 3 }, fn: function(){} }
console.log(obj2) // { name: 'cat', info: { age: 4 }, fn: function(){} } 

当然还可以使用第三方库Lodash中的_.cloneDeep(value),强烈推荐这个库,功能非常强大!


关注公众号【麋鹿迷了路】,发送js获取更多学习资源

在这里插入图片描述

喜欢的小伙伴们点个赞吧(〃‘▽’〃) ̄ω ̄= ( ̄▽ ̄)~*

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值