分享web开发知识

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

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

js对象深拷贝浅拷贝

发布时间:2023-09-06 01:41责任编辑:胡小海关键词:js

对象的深拷贝于浅拷贝

对于基本类型,浅拷贝过程就是对值的复制,这个过程会开辟出一个新的内存空间,将值复制到新的内存空间。而对于引用类型来书,浅拷贝过程就是对指针的复制,这个过程并没有开辟新的堆内存空间,只是将指向该内存的地址进行了复制。然而对引用类型的浅拷贝会出现一个问题,那就是修改其中一个对象的属性,则另一个对象的属性也会改变。产生了问题那必然有相对解决的方法, 就这样深拷贝就开始入场了,深拷贝会开辟新的栈,两个对象对应两个不同的地址,这样一来,改一个对象的属性,也不会改变另一个对象的属性。
下面我们用代码看一下深拷贝于浅拷贝是如何实现的 :

对象的浅拷贝

对象的浅拷贝实现方法很简单,说白了就是一个for in 循环的事情 :

let obj = { ???nNum : 1, ???sName : 'aaron'};function shallowCopy(args) { ???let result = {}; ???????for(let item in args) { ???????if(args.hasOwnProperty(item)) { ???????????result[item] = args[item]; ???????}; ???}; ???return result;};shallowCopy(obj);

或者,我们可以使用最常见的jQuery来实现这个功能 :

$.extend({} , obj);

亦或者,我们也可以采用ES6的方法用一行代码实现相同的功能 :

Object.assign({} , obj);

对于浅拷贝就说到这了,如果有补充或者发现问题的大牛可以回复我或者邮件通知,我会第一时间进行回复,好了废话说多了,我们接下来看一下深拷贝

对象的深拷贝

如果我们把上面的obj稍微修改一下那浅拷贝就有心无力了 :

let obj = { ???nNum : 1, ???oAar : [1,2,3,4]};

我们不妨可以再用上面的方法试一下

let newObj = shallowCopy(obj);newObj === obj ?????// falsenewObj.oAar === obj.oAar ??// true

从上面的结果显示我们可以看出,newObj.oAar与obj.oAar指针所指的是同一个位置,那我们如何改正这个问题呢?

其实也很容易,我们将obj.oAar再看待为一个新的对象,对其再进行一次浅拷贝不就可以了吗??不说了,上代码

function deepCopy(args) { ???let result = {}; ???????for(let item in args){ ????????if(typeof args[item] === 'object' && args[item] !== null){ ????????????result[item] = deepCopy(args[item]); ????????}else{ ????????????result[item] = args[item]; ????????}; ????}; ???return result;};result(obj);

我们来验证一下

let newObj = result(obj);newObj === obj ?????// falsenewObj.oAar === obj.oAar ??// false

结果也显示我们实现了,ok

但是有没有其他的方式呢,比如说更简洁一些的,也是有的:

我们可以使用jQuery的$.extend(true, {}, obj),同样也可以实现,是不是觉得眼熟。前面我们说浅拷贝的时候也说过这个方法,但是多了一个为true的参数,$.extend()方法,第一个参数默认为false,当设置它为true时则会开启深拷贝模式。

想想还有没有什么其他的方式= ̄ω ̄=?

其实还有一个捷径可走

还是上面举的那个obj,我们对它再进行一次尝试

 let obj = { ???nNum : 1, ???oAar : [1,2,3,4] }; ?function deepCopy(args) { ?????let result = {}; ???????????try { ?????????result = JSON.parse(JSON.stringify(args)); ?????} ???????????return result; ?} ?let newObj = deepCopy(obj); ?newObj === obj ?????// false newObj.oAar === obj.oAar ??// false

ヾ(?`Д′?) 什么鬼,这样也行? 那还前面说那么多废话,直接上这个方法岂不是爽歪歪?

但是这里不得不说明一点,投机取巧往往能达到看似相同的结果,但是还是存在一些隐性的问题的

就如上面这种方式和递归的方法相比是有弊端的,比如它会抛弃对象的constructor。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object。

这种方法能正确处理的对象只有 Number, String, Boolean, Array, 扁平对象,即那些能够被 json 直接表示的数据结构。RegExp对象是无法通过这种方式深拷贝。

最后再说一种方法,可以使用Object.create()方法达到深拷贝的效果

function deepCopy(args) { ???let result = {}; ???????for(let item in args){ ??????????if(typeof args[item] === 'object' && args[item] !== null){ ??????????????result[item] = args[item].constructor === Array ? [] : ??????????????Object.create(prop); ??????????}else{ ??????????????result[item] = args[item]; ??????????}; ????}; ???????return result;}let newObj = deepCopy(obj); newObj === obj ?????// falsenewObj.oAar === obj.oAar ??// false

好了,更多的第三方库的方法我们就不一一列举了,原理更重要嘛,对吧。

最后我们来总结一下:

浅拷贝我们说了3种方法 :

  • 通过for...in循环来实现
  • 通过Object.assign()方法来实现
  • 通过jQuery中的$.extend()方法来实现

深拷贝我们同样说了四种方法 :

  • 通过递归的手法实现
  • 通过jQuery中的$.extend()添加true参数方法来实现
  • 通过JSON序列化反序列化来实现
  • 用过Object.create()方法来实现

除了这几种如果各位还想到了其他什么好的方法欢迎下方留言ヾ( ̄▽ ̄)

js对象深拷贝浅拷贝

原文地址:https://www.cnblogs.com/AaronShen/p/8406015.html

知识推荐

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