在JavaScript编程中,我们经常需要处理对象和数组的复制操作。深拷贝和浅拷贝是两种常见的复制方式,它们在实现上有着不同的特点和应用场景。本文将介绍在复制操作中常见深浅拷贝的区别与实现方式。
1.深浅拷贝的区别
共同点:都是进行复制操作。
浅拷贝:只复制引用,而未复制真正的值。
深拷贝:完全拷贝一份新的对象,会在堆内存中开辟新的空间,拷贝的对象被修改后,原对象不受影响。
使用 “=” 进行直接赋值操作时,基本数据类型为深拷贝,引用数据类型为浅拷贝。
2.深浅拷贝的实现方式
1.ES6扩展运算符
const obj = { name: 'luaox', age: 23, fn:()=>{} } const objCopy1 = { ...obj } objCopy1.age = 18 console.log(obj); // {name: 'luaox', age: 23, fn: ƒ} console.log(objCopy1); // {name: 'luaox', age: 18, fn: ƒ}
特点:只能实现一维对象或一维数组的深拷贝,可以拷贝内部函数。
2.Object.assign方法
const obj = { name: 'luaox', age: 23, fn:()=>{} } const objCopy2={} Object.assign(objCopy2,obj) objCopy2.age = 18 console.log(obj); // {name: 'luaox', age: 23, fn: ƒ} console.log(objCopy2); // {name: 'luaox', age: 18, fn: ƒ}
特点:只能实现一维对象的深拷贝,可以拷贝内部函数。
3.Array.prototype.concat方法
const arr =[1,2,3,4] const arrCopy1=[].concat(arr) arrCopy1[0]=10 console.log(arr); // [1, 2, 3, 4] console.log(arrCopy1); // [10, 2, 3, 4]
特点:只能实现一维数组的深拷贝,可以拷贝内部函数。
以上三种方法都是只能实现一维上的深拷贝,如果对象或数组嵌套层数过多,以上方法均不适用。
4.JSON.parse(JSON.stringify())方法
const obj={name:'luaox',age:18,hobby:['唱','跳'],fn:()=>{}} const objCopy=JSON.parse(JSON.stringify(obj)) objCopy.hobby[1]='篮球' console.log(obj); console.log(objCopy);
特点:对于多层嵌套的数组或对象仍可进行深拷贝,但不会拷贝内部函数。
5.递归函数实现深拷贝
function deepCopy(obj){ let newObj=obj instanceof Array?[]:{} for(let key in obj){ let value=obj[key] newObj[key]=(value!==null && typeof value==='object')?deepCopy(value):value } return newObj } const obj = { name: 'luaox', age: 18, hobby: ['唱', '跳',['书','画']], fn: () => {console.log(1); } } const objCopy=deepCopy(obj) objCopy.hobby[2][0] = 'rap' console.log(obj); console.log(objCopy);
特点:自定义编写函数方法显得更为灵活,但要考虑到更多的特殊情况。
6.lodash库
lodash是一套工具库,可以通过script标签直接引入或使用npm进行下载导入,其内部封装了很多字符串、数组、对象等常见数据类型的处理函数。其中cloneDeep方法内部实现了深拷贝。
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script> <script> const obj = { name: 'luaox', age: 18, hobby: ['唱', '跳', ['书', '画']], fn: () => { console.log(1); } } // 语法:_.cloneDeep(要被克隆的对象) const objCopy = _.cloneDeep(obj) objCopy.hobby[2][0] = 'rap' console.log(obj); console.log(objCopy); </script>
特点:简单方便。