分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 代码编程

js实现浅拷贝和深拷贝

发布时间:2023-09-06 02:11责任编辑:熊小新关键词:js

浅拷贝和深拷贝都只针对于像Object, Array这样的复杂对象,

区别:浅拷贝只复制对象的第一层属性、深拷贝可以对对象的属性进行递归复制

如果数组元素是基本类型,就会拷贝一份,互不影响,而如果是对象或者数组,就会只拷贝对象和数组的引用,这样我们无论在新旧数组进行了修改,两者都会发生变化,这种叫浅拷贝。 

深拷贝就是指完全的拷贝一个对象,即使嵌套了对象,两者也相互分离,修改一个对象的属性,也不会影响另一个。

一、浅拷贝

1、数组的浅拷贝

 (1)、可用concat、slice返回一个新数组的特性来实现拷贝

var arr = [‘old‘, 1, true, null, undefined];var new_arr = arr.concat(); // 或者var new_arr = arr.slice()也是一样的效果;new_arr[0] = ‘new‘;console.log(arr); // ["old", 1, true, null, undefined]console.log(new_arr); // ["new", 1, true, null, undefined]/2、

 (2)、还有for循环也能实现数组的浅拷贝

var arr = [1,2,3,4,5]var arr2 = copyArr(arr)function copyArr(arr) { ???let res = [] ???for (let i = 0; i < arr.length; i++) { ????res.push(arr[i]) ???} ???return res}

(3)、ES6扩展运算符实现数组的浅拷贝

var arr = [1,2,3,4,5]var [ ...arr2 ] = arrarr[2] = 5console.log(arr)console.log(arr2)

但是如果数组嵌套了对象或者数组的话用concat、slice拷贝只要有修改会引起新旧数组都一起改变了,比如:

var arr = [{old: ‘old‘}, [‘old‘]];var new_arr = arr.concat();arr[0].old = ‘new‘;new_arr[1][0] = ‘new‘;console.log(arr); // [{old: ‘new‘}, [‘new‘]]console.log(new_arr); // [{old: ‘new‘}, [‘new‘]]

2、对象的浅拷贝

(1)、万能的for循环

var obj = { ?name: ‘FungLeo‘, ?sex: ‘man‘, ?old: ‘18‘}var obj2 = copyObj(obj)function copyObj(obj){ ?let res = {} ?for (var key in obj) { ???res[key] = obj[key] ?} ?return res}

(2)、ES6扩展运算符实现对象的浅拷贝

var obj = { ?name: ‘FungLeo‘, ?sex: ‘man‘, ?old: ‘18‘}var { ...obj2 } = objobj.old = ‘22‘console.log(obj)console.log(obj2)

同样如果对象里面还嵌套其他引入数据类型,对象的浅拷贝也无法做到真正的拷贝深层的东西

Object.assign()也可以对数组、对象实现浅拷贝

下面是浅拷贝一个通用方法,实现思路:遍历对象,把属性和属性值都放在一个新的对象里

var shallowCopy = function (obj) { ?// 只拷贝对象 ?if (typeof obj !== ‘object‘) return; ?// 根据obj的类型判断是新建一个数组还是一个对象 ?var newObj = obj instanceof Array ? [] : {}; ?// 遍历obj,并且判断是obj的属性才拷贝 ?for (var key in obj) { ???if (obj.hasOwnProperty(key)) { ?????newObj[key] = obj[key]; ???} ?} ?return newObj;}

二、深拷贝

下面是深拷贝一个通用方法,实现思路:拷贝的时候判断属性值的类型,如果是对象,继续递归调用深拷贝函数

var deepCopy = function(obj) { ?// 只拷贝对象 ?if (typeof obj !== ‘object‘) return; ?// 根据obj的类型判断是新建一个数组还是一个对象 ?var newObj = obj instanceof Array ? [] : {}; ?for (var key in obj) { ???// 遍历obj,并且判断是obj的属性才拷贝 ???if (obj.hasOwnProperty(key)) { ?????// 判断属性值的类型,如果是对象递归调用深拷贝 ?????newObj[key] = typeof obj[key] === ‘object‘ ? deepCopy(obj[key]) : obj[key]; ???} ?} ?return newObj;}

还有一种比较实用的深拷贝技巧:

function deepcopy(obj){ ???return JSON.parse(JSON.stringify(obj));}

但这种方法会存在一些缺陷,比如无法处理function,无法处理Reg,无法处理循环引用对象,但一般来说是够用的

js实现浅拷贝和深拷贝

原文地址:https://www.cnblogs.com/leelam/p/9515166.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved