JavaScript面试题:什么是深浅拷贝?怎么实现深浅拷贝?Object.assign()方法介绍?

深浅拷贝

1、什么是深浅拷贝

深浅拷贝都只是针对引用对象来区分的,其他基本类型并不区分什么深浅拷贝。

浅拷贝
浅拷贝是对内存地址的复制,让目标对象指针和源对象指向同一片内存地址。

当内存销毁的时候,指向对象的指针必须重新定义才能够使用。

深拷贝
深拷贝是指拷贝对象的具体内容,而内存地址是自主分配的,拷贝结束之后两个对象虽然存的值是一样的,但是内存地址不一样。

2、深浅拷贝的实现

  • 浅拷贝实现方式

1、方式一:直接赋值即可实现对象浅拷贝

// 浅拷贝
let obj1 = { a: 0, b: { c: 0 } }
let obj2 = obj1
console.log(obj1); // { a: 0, b: { c: 0 } }
console.log(obj2); // { a: 0, b: { c: 0 } }

console.log(obj1 === obj2); // true
// 修改obj1中的a属性
obj1.a = 1

// 可以看到obj2中的a属性的值也改变了,这样就能证明obj2只是对obj1对象内存地址的复制,指针还是指向obj1对象内存地址
console.log(obj2); // { a: 1, b: { c: 0 } }

2、方式二:解决赋值

let obj1 = {info:{name:"nick", age:23}}
// 通过展开元素符进行浅复制
let {info} = obj1

3、其他的数组的一些方法,例如 Array.property.slice() 以及 Array.property.concat() 也可以实现浅拷贝

4、自定义浅拷贝:

function shallowCopy(obj) {
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }

  let copy = Array.isArray(obj) ? [] : {};

  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      copy[key] = obj[key];
    }
  }

  return copy;
}
  • 深拷贝实现方式

方式一:JSON.stringify()方法和JSON.parse()方法实现

let obj1 = {a:0,b:{c:"hello"}}

let obj2 = JSON.parse(JSON.stringify(obj1))
console.log(obj2); // { a: 0, b: { c: 'hello' } }

obj1.a = 1
console.log(obj1); // { a: 1, b: { c: 'hello' } }
console.log(obj2); // { a: 0, b: { c: 'hello' } }

// 可以看到,obj1的a属性取值改变并不会影响到obj2中的a属性取值,
// 所以也就可以说明这两个对象内存地址并不一样

需要注意的是,JSON.stringify() 和 JSON.parse() 方法只能处理支持 JSON 格式的数据类型,包括对象、数组、字符串、数字、布尔值和 null。它们无法处理特殊类型(如函数、symble、正则表达式、日期)以及循环引用等情况。

方式二:通过assign()方法实现(特殊)
关于assign()方法的介绍可以看MDN官方

这个方法比较特殊,当对象嵌套层次小于2层,则是深拷贝,大于等于2层时则是浅拷贝,具体原理:利用拼接原理,对对象进行拼接,将后续对象的内容插入到第一个参数指定的对象,并且不会修改第一个参数之后的对象。

let obj1 = { a: 0, b: { c: "hello" } }
let obj2 = Object.assign({}, obj1)

obj1.a = 1 // 小于2层的为深拷贝
obj1.b.c = '你好' // 大于等于层的为浅拷贝
console.log(obj1); //  { a: 1, b: { c: '你好' } }
console.log(obj2); // { a: 0, b: { c: '你好' } }

方式三:自定义深拷贝(递归实现)

function deepCopy(source) {
    if (source === null || typeof source !== 'object' || source instanceof Date || source instanceof RegExp) {
        return source;
    }

    let copy = Array.isArray(source) ? [] : {}

    for (let key in source) {
        if (source.hasOwnProperty(key)) {
            copy[key] = deepCopy(source[key]);
        }
    }

    return copy;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值