js 对象如何深拷贝

JS中对象深拷贝的几种方法

既然看到了这里,想必已经知道什么是深拷贝以及它的作用,这里不再赘述概念

1、递归

有算法基础都可以写出来、简单易懂;可以拷贝所有成员属性和方法,推荐使用

//核心代码
function deepCopy(raw) {
        let obj = {}
        for (const k in raw) {
            if (raw.hasOwnProperty(k)) {
                const type = typeof raw[k]
                switch (type) {
                    case "object":
                        obj[k] = deepCopy(raw[k])
                        break
                    case "function":
                        obj[k] = function () {
                            return raw[k].call(obj, ...arguments)
                        }
                        break
                    default:
                        obj[k] = raw[k]
                }
            }
        }
        return obj
    }
//测试一下拷贝后的属性、对象、函数是否正常
 let obj = {
        name: "张三",
        getName() {
            console.log(this.name)
        },
        relation: {
            friend: "李四",
            say(a) {
                console.log(this.friend + a)
            }
        }
    }
    let deepO = deepCopy(obj)//拷贝obj
    
    /*检验第一层属性及方法*/
    deepO.name = "胡汉三"
    console.log(obj.name) //依然是`张三`,测试通过
    deepO.getName()//`胡汉三`,测试通过

    /*检验深层次属性及方法*/
    deepO.relation.friend = "王大爷"
    console.log(obj.relation.friend) //依然是`李四`,测试通过
    deepO.relation.say(",你好")//`王大爷,你好`,测试通过

2、 JSON对象拷贝

缺点:无法拷贝函数

 let deepO = JSON.parse(JSON.stringify(obj))//拷贝obj

 /*检验第一层属性及方法*/
 deepO.name = "胡汉三"
 console.log(obj.name) //依然是`张三`,测试通过
 deepO.getName()//error

 /*
 检验深层次属性及方法
 */
 deepO.relation.friend = "王大爷"
 console.log(obj.relation.friend) //也变成了 `王大爷`,结果不符合预期
 deepO.relation.say(",你好")//error

3、 Object.assign({ },obj)

实际上这是一个浅拷贝函数,可以拷贝所有成员属性和方法

 let deepO = Object.assign({},obj)//拷贝obj
 
 /*检验第一层属性及方法*/
  deepO.name = "胡汉三"
  console.log(obj.name) //依然是`张三`,测试通过
  deepO.getName()//`胡汉三`,测试通过

  /*
  检验深层次属性及方法
  ===不符合预期===
  */
  deepO.relation.friend = "王大爷"
  console.log(obj.relation.friend) //也变成了 `王大爷`,结果不符合预期  
  deepO.relation.say(",你好")//`王大爷,你好`,结果不符合预期  

所以方案最好的应该是第一种,如果不需要拷贝函数使用第二种,第三中只适合一层对象,大家可以根据需求使用哦

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值