浅拷贝深拷贝对象的几种方法及区别

浅拷贝深拷贝对象的几种方法及区别


前言

总结拷贝对象的方法及浅拷贝和深拷贝的区别


一、浅拷贝

被拷贝对象有第二层或多层嵌套对象的时候,对里层的对象只拷贝了内存地址,里层嵌套的对象数据发生变化时,拷贝出来的对象也会发生改变,对于其他的基本类型不会发生变化

1、方法1

js原生赋值方法

代码如下(示例):

		var obj={
		userNeme:"xiaoming",
		age:20
		}
        var obj1=obj;
        obj.phone=12356564;
        console.log(obj);//{userNeme:"xiaoming",age:20,phone:12356564};
        console.log(obj1);//{userNeme:"xiaoming",age:20,phone:12356564};

此时无论是obj还是obj1的任何一个数据发生变化时,两者都会发生变化,因为此时两者是共用的同一个内存地址。
这种方法相当于一种浅层次的拷贝,两者共用一个内存,两者的数据相互影响

2、方法2

js原生for in方法

代码如下(示例):

		var obj={
            userNeme:"xiaoming",
            age:20,
            obj2:{
                email:"54648468@qq.com"
            }   
		}
        var obj1 = {};
        for(var item in obj){
            obj1[item]=obj[item]
        };
        obj.phone=12356564;
        obj.obj2.address="河南";
        console.log(obj);//{userNeme: "xiaoming", age: 20, obj2: {email: "54648468@qq.com", address: "河南"}, phone: 12356564}
        console.log(obj1);//{userNeme: "xiaoming", age: 20, obj2: {email: "54648468@qq.com", address: "河南"}}

此时obj中的obj2的数据发生变化时,obj1中的obj2的数据也会发生变化,因为此时两者是相同的内存地址;
obj中的简单类数据发生变化时不会影响到obj1中的简单类数据,obj和obj1的内存地址是不同的。

3、方法3

使用ES6中的拓展运算符

代码如下(示例):

		var obj={
            userNeme:"xiaoming",
            age:20,
            obj2:{
                email:"54648468@qq.com"
            }   
		}
        var obj1 = { ...obj };
        obj.phone=12356564;
        obj.obj2.address="河南";
        console.log(obj);//{userNeme: "xiaoming", age: 20, obj2: {email: "54648468@qq.com", address: "河南"}, phone: 12356564}
        console.log(obj1);//{userNeme: "xiaoming", age: 20, obj2: {email: "54648468@qq.com", address: "河南"}}

此时obj中的obj2的数据发生变化时,obj1中的obj2的数据也会发生变化,因为此时两者是相同的内存地址。
obj中的简单类数据发生变化时不会影响到obj1中的简单类数据,obj和obj1的内存地址是不同的。

4、方法4

使用ES6中Object的assign方法

代码如下(示例):

		var obj={
            userNeme:"xiaoming",
            age:20,
            obj2:{
                email:"54648468@qq.com"
            }   
		}
        var obj1 = Object.assign({},obj);
       	obj.phone=12356564;
        obj.obj2.address="河南";
        console.log(obj);//{userNeme: "xiaoming", age: 20, obj2: {email: "54648468@qq.com", address: "河南"}, phone: 12356564}
        console.log(obj1);//{userNeme: "xiaoming", age: 20, obj2: {email: "54648468@qq.com", address: "河南"}}

此时obj中的obj2的数据发生变化时,obj1中的obj2的数据也会发生变化,因为此时两者是相同的内存地址。
obj中的简单类数据发生变化时不会影响到obj1中的简单类数据,obj和obj1的内存地址是不同的。

二、深拷贝

1、方法1

使用JSON字符串的方法

代码如下(示例):

		var obj={
            userNeme:"xiaoming",
            age:20,
            obj2:{
                email:"54648468@qq.com"
            },
            ignore:undefined,
            ignoreFunction(){
                console.log(345);
            }
		}
        var obj1 = JSON.parse(JSON.stringify(obj))//会忽略掉对象obj里面的undefined和函数
        obj.phone=12356564;
        obj.obj2.address="河南";
        console.log(obj);//{userNeme: "xiaoming", age: 20, obj2: {email: "54648468@qq.com", address: "河南"}, ignore: undefined, ignoreFunction: ƒ, …}
        console.log(obj1);//{userNeme: "xiaoming", age: 20, obj2: {email: "54648468@qq.com"}}

此时obj中的obj2的数据发生变化时,obj1中的obj2的数据不会发生变化,因为此时两者是不同的内存地址。
obj中的简单类数据发生变化时不会影响到obj1中的简单类数据,obj和obj1的内存地址是不同的。

需要注意的是: 这个方法在拷贝对象时 ,如果对象里面的属性值含有undefined和函数的话会被忽略掉,无法拷贝到新的对象中,这是由于JSON的特性导致的,JSON字符串在转化为JSON对象的时候会自动忽略掉undefined和函数

2、方法2

使用递归的方法

代码如下(示例):

		var obj = {
            userNeme: "xiaoming",
            age: 20,
            obj2: {
                email: "54648468@qq.com"
            },
            ignore: undefined,
            ignoreFunction: function () {
                console.log(345);
            }
        }
       function deepCopy(copyobj){
            var obj1=Array.isArray(copyobj)?[]:{}
            for(var item in copyobj){
                if(typeof copyobj[item]=="object"){
                    obj1[item]=deepCopy(copyobj[item])
                }else{
                    obj1[item]=copyobj[item]
                }
            }
            return obj1
        }
        let newobj=deepCopy(obj)//obj2中的内容无法拷贝出来
        obj.phone = 12356564;
        obj.obj2.address = "河南";
        console.log(obj);//{userNeme: "xiaoming", age: 20, obj2: {email: "54648468@qq.com", address: "河南"}, ignore: undefined, ignoreFunction: ƒ, …}
        console.log(obj1);//{userNeme: "xiaoming", age: 20, obj2: {email: "54648468@qq.com"}, ignore: undefined, ignoreFunction: ƒ}

此时obj中的obj2的数据发生变化时,obj1中的obj2的数据不会发生变化,因为此时两者是不同的内存地址。
obj中的简单类数据发生变化时不会影响到obj1中的简单类数据,obj和obj1的内存地址是不同的。

3、方法3

使用jQuery的extend方法

代码如下(示例):

		var obj = {
            userNeme: "xiaoming",
            age: 20,
            obj2: {
                email: "54648468@qq.com"
            },
            ignore: undefined,
            ignoreFunction: function () {
                console.log(345);
            }
        }
		var obj1={};
		$.extend(true,obj1, obj);
        obj.phone = 12356564;
        obj.obj2.address = "河南";
		// true为深拷贝(false为浅拷贝) 省略时默认为false,obj1为要扩展的对象,后边的就是扩展的内容,可以有多个
		// 扩展的内容可以识别函数,不能识别undefined
        console.log(obj);//{userNeme: "xiaoming", age: 20, obj2: {email: "54648468@qq.com", address: "河南"}, ignore: undefined, ignoreFunction: ƒ, …}
        console.log(obj1);//{userNeme: "xiaoming", age: 20, obj2: {email: "54648468@qq.com"}, ignoreFunction: ƒ}

此时obj中的obj2的数据发生变化时,obj1中的obj2的数据不会发生变化,因为此时两者是不同的内存地址。
obj中的简单类数据发生变化时不会影响到obj1中的简单类数据,obj和obj1的内存地址是不同的。

需要注意的是: 这个方法在拷贝对象时 ,扩展的内容可以识别函数,不能识别undefined


总结

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值