深拷贝——将对象拷贝到底

假设我们有一个这样的需求,我们需要编辑修改一份表单,修改后提交之前想还原到之前的表单的值,这样我们就需要对原始表单有一个备份

// 原始表单
var form = {
    name: '张三',
    age: 18,
    sex: 1,
    score:{
        math: 99,
        chinese: 80,
        english: 90
    }
}
复制代码

1.直接复制

// 备份一份表单
var formBank = form

// 然后我们现在要修改form的sex
form.sex = 0
console.log(formBank.sex) // 0
// 很显然这样子formBank的sex也会变成0
// 因为formBank是指向了form对象的引用
复制代码

2.取值赋值

//那我们使用取值赋值的方式来试试
function copy(sub, sup) {
  for (var key in sup) {
    sub[key] = sup[key];
  }
}
var formCopy = {}
copy(formCopy, form)
//这样我们就通过取值赋值的方式得到了一个新的对象
//同样我们来修改一下form.age
form.age = 20
console.log(formCopy.age) // 20
//新的对象formCopy似乎不会被form对象影响
//我们再修改score.math试试
form.score.math = 100
console.log(formCopy.math) // 100
// 好像不行,因为实际上这个情况是跟上一个方式一样的,
// formCopy.score的指向就是form.score对象引用
复制代码

3.通过JSON的parse 和 stringify转换

// 先将form对象转换成json字符串再转换会对象,这样就不会copy出来的对象就不会指到form的引用了
var formParse = JSON.parse(JSON.stringify(form))
form.name = '李四'
console.log(formParse.name) // 张三
form.score.chinese = 88
console.log(formParse.score.chinese) // 80
复制代码

假如我们是处理一般的后台请求过来的数据的话使用这个方法应该是最快捷方便的,但是我们假设给form添加这样一个属性

form.func = function(){
	console.log('this is a function')
}
// 在通过JSON的parse和stringify转换会怎么样呢
// 我们先看看JSON.stringify(form)
console.log(JSON.stringify(form)
//{"name":"李四","age":19,"sex":0,"score":{"math":99,"chinese":80,"english":90}}
//很明显这样并不能达到我们想要的效果,转换成字符串后func不见了这样再转换成对象的话也是一样的
复制代码

4.深度拷贝

其实我们在第二种方法的时候就可以解决这个问题了,我们只要通过递归把对象取值赋值到底即可

function deepCopy (sub, sup) {
  for (var key in sup) {
    if (typeof sup[key] === 'object') {
      sub[key] = {};
      if(sup[key].length) {
        sub[key] = []
      }
      deepCopy (sub[key], sup[key]);
    } else {
      sub[key] = sup[key];
    } 
  }
}

//我们给form添加一些属性进行测试看看效果
form.func = function() {
	console.log('this is a function')
}
form.arr = [1, 2, 3]
var formDeepCopy = {}
deepCopy(formDeepCopy, form)
console.log(formDeepCopy)
/***
{
 age: 19, arr: [1, 2, 3]
 func: function() {
	console.log('this is a function')
 },
 name: '李四',
 score: {math: 100, chinese: 80, english: 90},
 sex: 0
}
***/
复制代码

转载于:https://juejin.im/post/5ad5974e5188255c27226dff

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值