js面试题之——深浅拷贝

本文探讨JavaScript中深浅拷贝的概念,特别是在处理引用数据类型时遇到的问题。文章介绍了基本数据类型与引用数据类型的区别,重点讲解了深拷贝与浅拷贝,并通过实例分析了concat、slice、Object.assign()以及...展开符等方法在拷贝时的行为。此外,还讨论了JSON.stringify/parse实现深拷贝的限制和递归实现深拷贝的常见方案。
摘要由CSDN通过智能技术生成

一直以来倒是没有仔细的思考过深浅拷贝的问题,最近有听到小伙伴在讨论,全面了解了一下,深拷贝并没有那么简单。现在让我们来一起探讨深浅拷贝相关的内容吧。

基本数据类型、引用数据类型

为什么会出现深浅拷贝的问题,主要因为在于js中所有的数据类型分为基本数据类型和引用数据类型两大类。

那么基本数据类型有哪些呢:NumberStringBooleanUndefinedNullSymbolBigInt

引用数据类型,就是Object了,但是js封装了几个继承了Object原型属性的一些对象,ArrayFunctionDataErrorMapSet

基本数据类型与引用数据类型的区别

存储方式

基本数据类型和引用数据类型是根据存储方式划分的。基本数据类型在内存中占据固定大小,保存在栈内存中。引用数据类型的值是对象,保存在堆内存中,并会在栈内存中存储该对象的变量标识符以及对象在堆内存中的存储地址。

赋值方式

所以在使用基本数据类型和引用数据类型的时候,关于赋值问题就需要多多思量了。

基本数据类型

基本数据类型的赋值方式,是从一个变量向另一个新变量复制基本类型的值,会创建这个值的一个副本,并将该副本赋值给新变量。

let a = 2;
let b = a;
console.log(a)
console.log(b)

// 修改b的值不会影响a的值
b = 3;
console.log(a)
console.log(b)
引用数据类型

引用数据类型从一个变量向另一个新变量复制引用数据类型的地址,将新复制的地址赋值给新变量,最终两个变量存储的是相同的地址,指向的是堆内存中同一块存储空间。通过一个变量修改对象属性,就会影响另一个变量指向的对象内容。

let c = {
   
    a: 1,
    b: 2,
    c: 3
}
let d = c
c.c = 5
console.log(d.c)

我们可以看到,通过c变量去修改该对象的c属性,d变量会被影响。那么引用数据类型的这种赋值方式就会对我们的开发造成一定影响。如果我们只想要一个和当前对象一样的对象,但修改数据时不会互相影响,这时候该怎么办呢?

深拷贝、浅拷贝

根据前面讲到的一些简单的知识普及,大家应该都知道了,所谓的深浅拷贝一定是针对于引用数据类型来说的,那么什么是深浅拷贝呢?

  • 浅拷贝:仅仅是复制了引用,彼此之间的操作会相互影响,指向的是同一块堆内存空间。前面讲到的=赋值就是浅拷贝。
  • 深拷贝:在堆中重新分配内存,不同的地址,相同的值,互不影响。

JavaScript中的拷贝

讲到了深浅拷贝,一定会有些疑问,js中有不少的拷贝方法,那么这些方法它们。。。到底是深拷贝还是浅拷贝。毕竟如果连这都搞不懂,在用的时候就很容易出一些乌龙事件。

concat

concat,用于连接两个或多个数组。
concat,方法不会更改现有数组,而是返回一个新数组,其中包含已连接数组的值。
看定义应该是深拷贝,我们可以来测试一下:

let a = [1,2,3,5,6]
let b = [7,8,9]
let c = a.concat(b)
console.log(c) //[1, 2, 3, 5, 6, 7, 8, 9]
a[0] = 2;
console.log(a) //[2,2,3,5,6]
console.</
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值