每日技术:浅复制和深复制,slice()
前言:学习不是一件容易的事。加油~
浅复制和深复制
一直对浅复制(也叫浅拷贝)和深复制(也叫深拷贝)这两个概念不清楚。
深复制和浅复制只针对Object,Array这样复杂的对象。
以下参考:https://www.jianshu.com/p/0d7bd31ccf43
深复制和浅复制最根本的区别在于是否是真正获取了一个对象的复制实体,而不是引用。
深复制在计算机中开辟了一块内存地址用于存放复制的对象
浅复制仅仅是指向被复制的内存地址,如果原地址中对象被改变了,那么浅复制出来的对象也会相应改变
所谓的浅复制,只是拷贝了基本数据类型的数据,而引用类型数据,复制后也是会发生引用,我们把这种拷贝叫做浅复制。
以下内容来自知乎 邹润阳的回答
一个简单的浅复制实现:
var obj = { a: 1, arr: [2, 3] } var shallowObj = shallowCopy(obj) function shallowCopy(src) { var dst = {}; for (var prop in src) { if (src.hasOwnProperty(prop)) { dst[prop] = src[prop] } } return dst; }
因为浅复制只会将对象的各个属性进行一次复制,并不会进行递归复制
而深复制则不同,它不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深复制的方法递归复制到新对象上。这就不会存在数组对象属性指向同一个对象的问题
以下内容参考:https://segmentfault.com/q/1010000006865450
浅复制举例代码:
Array.clone = function(arr) { const ans = []; for(let i = 0; i < arr.length; i++) { ans[i] = arr[i]; } return(ans); } let a = [1,2,3,[4,5,6],[7,8,9]], b = Array.clone(a); console.log(a === b); //false console.log(a[3]); //[4,5,6] console.log(a[3] === b[3]); //true console.log(a[4] === b[4]); //true
深复制举例代码:
Array.clone = function(arr) { const ans = []; for(let i = 0; i < arr.length; i++) { if(arr[i].length) { ans[i] = Array.clone(arr[i]); } else { ans[i] = arr[i]; } } return(ans); } let a = [1,2,3,[4,5,6],[7,8,9]], b = Array.clone(a); console.log(a === b); //false console.log(a[3]); //[4,5,6] console.log(a[3] === b[3]); //false console.log(a[4] === b[4]); //false
关于深浅复制的笔记写得非常散乱,没办法,感觉不是很好懂。就酱先。
Array.prototype.slice()
slice()方法返回一个新的数组对象,这一对象是一个由begin和end决定的原数组的浅拷贝(包括begin,不包括end)。原始数组不会被改变。
怎么理解这里说的浅拷贝?(为了理解这一点才有了上面的浅复制和深复制的学习内容)
列举一段简单的代码:
var arr0 = [1, 9, [2, 3], [4, 5]]; var arr1 = arr0.slice(1); console.log(arr1); // [9, [2, 3], [4, 5]] console.log(arr1[1] == arr0[2]); // true
这里说的浅拷贝是针对数组对象成员的浅拷贝
深拷贝和浅拷贝的概念是针对Object,Array这种复杂的引用型数据类型而言的。
Array.from()
Array.from()方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历的(iterable)的对象
利用Array.from()方法复制一个数组
var arr1 = [1, [1, 2], 3] var arr2 = Array.from(arr1); console.log(arr1 === arr2); // false console.log(arr1[1] === arr2[1]); // true
可见对于数组成员该方法返回的是浅拷贝的结果。
常见的类数组对象有:
- DOM操作返回的NodeList集合
- 函数内部的arguments对象
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理