JavaScript深浅拷贝原理实现

JS深浅拷贝与赋值

JavaScript基本数据类型的变量存储在栈中,引用数据类型则存储在堆中,但是引用数据类型的存储地址则保存在栈中。
  • 赋值

    当我们把一个对象赋值给一个新的变量时候,赋的其实是该对象在栈中的地址,而不是堆中的数据,也就是两个对象指向的是同一个存储空间,无论哪个对象发生改变,其实都是改变的存储空间的内容,因此,两个对象是联动的。

    var programmer = {
    	name: '张三',
    	attr: ['前端', ['Vue', 'React', 'Angular'], '后端']
    }
    
    var programmer1 = programmer
    programmer1.name = 'lisi'
    programmer1.attr[0] = '测试'
    
    console.log(programmer)
    console.log(programmer1)
    

    在这里插入图片描述

  • 浅拷贝

    重新在堆中创建内存,拷贝前后对象的基本数据类型互不影响,但拷贝前后对象的引用类型因共享同一块内存,会相互影响

    // 方法一
    var programmer = {
    	name: '张三',
    	attr: ['前端', ['Vue', 'React', 'Angular'], '后端']
    }
    
    function shallowClone(obj) {
    	var target = {}
    	for (let i in obj) {
    		if (obj.hasOwnProperty(i)) {
    			target[i] = obj[i]
    		}
    	}
    	return target
    }
    
    var programmer1 = shallowClone(programmer)
    programmer1.name = 'lisi'
    programmer1.attr[0] = '测试'
    
    console.log(programmer)
    console.log(programmer1)
    
    // 方法二
    var programmer1 = {...programmer}
    
    programmer1.name = 'lisi'
    programmer1.attr[0] = '测试'
    
    console.log(programmer)
    console.log(programmer1)
    
    // 方法三
    var programmer1 = Object.assign({}, programmer)
    
    programmer1.name = 'lisi'
    programmer1.attr[0] = '测试'
    
    console.log(programmer)
    console.log(programmer1)
    
    // 方法四
    // 还有lodash中的 _.clone(),这里就不演示了
    

    在这里插入图片描述

  • 深拷贝

    从堆内存中开辟一个新的区域存放新对象,对对象中的子对象进行递归拷贝,拷贝前后的两个对象互不影响

    // 方法一
    var programmer = {
    	name: '张三',
    	attr: ['前端', ['Vue', 'React', 'Angular'], '后端']
    }
    
    function deepClone(obj) {
    	let target
    	if (typeof obj === 'object') {
    		if (Array.isArray(obj)) {
    			target = []
    			for (let i in obj) {
    				target.push(deepClone(obj[i]))
    			}
    		} else if (obj === null) {
    			target = null
    		} else if (obj instanceof Date) {
    			target = new Date(obj)
    		} else if (obj instanceof RegExp) {
    			target = new RegExp(obj)
    		} else {
    			target = {}
    			for (let i in obj) {
    				target[i] = deepClone(obj[i])
    			}
    		}
    	} else {
    		target = obj
    	}
    	return target
    }
    
    var programmer1 = deepClone(programmer)
    programmer1.name = 'lisi'
    programmer1.attr[0] = '测试'
    
    console.log(programmer)
    console.log(programmer1)
    
    // 方法二
    var programmer1 = JSON.parse(JSON.stringify(programmer))
    
    programmer1.name = 'lisi'
    programmer1.attr[0] = '测试'
    
    console.log(programmer)
    console.log(programmer1)
    
    // 方法三
    // lodash中的 _.cloneDeep() 这里就不演示了
    

    在这里插入图片描述
    在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Y shǔ shǔ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值