浅拷贝和深拷贝

/* 
					最新的ECMAScript标准定义了 8 种数据类型:
					6 种原始数据类型:Boolean,undefined,Number,BigInt,String,Symbol
					null Object Function
				 */

				/* 	
					数据分为: 基本数据类型 & 引用数据类型
					基本数据类型:String,Number,Boolean,null,undefined,Symbol.(基本数据类型都是直接存储在栈中的数据)
					引用数据类型:Array,Object.(引用数据类型存储的是该对象在栈中引用,真实的数据存储在内存中) 
					*/

				// 基本数据类型
				/* let str1 = '123'
				let str2 = str1
				str2 = '456'
				console.log(str1) //123
				console.log(str2) //456 */

				// 引用数据类型
				/* let arr1 = [1, 2, 3]
				let arr2 = arr1
				arr2.push(4)
				console.log(arr1) // [1, 2, 3, 4]
				console.log(arr2) // [1, 2, 3, 4] */

				/* 
				 如上,由于基本数据类型是直接存储的,所以如果我们对基本数据类型进行拷贝,然后修改新数据后,不会影响到原数据。
				 
				 而当你对引用数据类型进行拷贝,然后修改新数据后,它就会影响到原数据
				 */

				/* 
				 赋值:引用地址的拷贝。修改赋值后的数据,不管是基本数据类型还是引用数据类型,都会影响到原数据。
				 浅拷贝:一层拷贝。在浅拷贝中,修改基本数据类型不会影响原有数据的基本数据类型,修改引用数据类型会影响原有的数据类型。
				 深拷贝:无限层级拷贝。在深拷贝中,修改基本数据类型和引用数据类型都不会影响原有的数据类型。
				 */

				// 手写浅拷贝
				/* const arr1 = [2,1,1,['rose','lisa'],327]
				const shallowClone = (arr) => {
					const pcy = []
					for (let p in arr) {
						if (arr.hasOwnProperty(p)) {
							pcy[p] = arr[p]
						}
					}
					return pcy
				}
				const arr2 = shallowClone(arr1)
				arr2[3].push('彩松鼠')
				arr2[4] = 521
				console.log(arr1,'原始数据')
				console.log(arr2,'浅拷贝并修改') */
				/* 
				 修改引用数据类型的时候会影响到原数据,修改基本类型不会影响原数据
				 for...in:遍历 Object 对象 arr1,将可枚举值列举出来。
				 hasOwnProperty():检查该枚举值是否属于该对象 arr1,如果是继承过来的就去掉,如果是自身的则进行拷贝。
				 */

				// 实现快速浅拷贝
				/* 
					Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。
					但是需要注意的是,Object.assgin() 进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身。 
					Object.assign() 对于第一层的数据来说,是深拷贝,对于第二层及以上的数据来说,是浅拷贝。
				*/

				/* const obj1 = {
					username: '211',
					skill: {
						music: ['make you mine', 'ghosts'],
						read: 'book'
					},
					idol: ['rose', 'lisa', 'jisoo', 'jennie']
				}
				const obj2 = Object.assign({}, obj1)
				obj2.username = '贰壹壹' //修改基本类型
				obj2.skill.music.push('18') //修改二层引用类型
				obj2.skill.read = 'novel book' //修改二层基本类型
				obj2.idol = ['BLACKPINK'] //修改引用类型

				console.log(obj1, '原数据')
				console.log(obj2, '浅拷贝并修改') */
				
				/* 
					concat() 是数组的一个内置方法,用户合并两个或者多个数组。这个方法不会改变现有数组,而是返回一个新数组。
				 修改基本类型不影响原数据,修改引用类型会影响原数据
				 */
				/* const arr1 = [211,{idol: 'BLAKCPINK'}]
				const arr2 = arr1.concat()
				arr2[0] = 327
				arr2[1].idol = '朴彩英'
				console.log(arr1, '原数据')
				console.log(arr2, '浅拷贝并修改') */
				
				/* 
				 slice() 也是数组的一个内置方法,该方法会返回一个新的对象。不会改变原数组
				 和concat()浅拷贝一模一样
				 */
				/* const arr1 = [211,{idol: 'BLAKCPINK'}]
				const arr2 = arr1.slice()
				arr2[0] = 327
				arr2[1].idol = '朴彩英'
				console.log(arr1, '原数据')
				console.log(arr2, '浅拷贝并修改') */
				
				/* 
				 ... 展开运算符
				 是 ES6 中新提出来的一种运算符。
				 在拷贝数组、对象以及拼接数组等方面都可以使用。
				 */
			/* 	// 浅拷贝数组
				const arr1 = [211,{idol: 'BLAKCPINK'}]
				const arr2 = [...arr1]
				arr2[0] = 327
				arr2[1].idol = '朴彩英'
				console.log(arr1, '原数据')
				console.log(arr2, '浅拷贝并修改')
				
				// 浅拷贝对象
				const obj1 = {
					username: '211',
					skill: {
						music: ['make you mine', 'ghosts'],
						read: 'book'
					},
					idol: ['rose', 'lisa', 'jisoo', 'jennie']
				}
				const obj2 = {...obj1}
				obj2.username = '贰壹壹' //修改基本类型
				obj2.skill.music.push('18') //修改二层引用类型
				obj2.skill.read = 'novel book' //修改二层基本类型
				obj2.idol = ['BLACKPINK'] //修改引用类型
				
				console.log(obj1, '原数据')
				console.log(obj2, '浅拷贝并修改') */
				
				// 深拷贝
				/* 
				 JSON.parse(JSON.stringify())。
				 
				 JSON.stringify():将对象转成 JSON 字符串。
				 JSON.parse():将字符串解析成对象。
				 
				 通过 JSON.parse(JSON.stringify()) 将 JavaScript 对象转序列化(转换成 JSON 字符串),再将其还原成 JavaScript 对象,一去一来我们就产生了一个新的对象,而且对象会开辟新的栈,从而实现深拷贝。
				 
				 注意,该方法的局限性:
				 1、不能存放函数或者 Undefined,否则会丢失函数或者 Undefined;
				 2、不要存放时间对象,否则会变成字符串形式;
				 3、不能存放 RegExp、Error 对象,否则会变成空对象;
				 4、不能存放 NaN、Infinity、-Infinity,否则会变成 null;
				 5、……更多请自行填坑,具体来说就是 JavaScript 和 JSON 存在差异,两者不兼容的就会出问题。
				 
				 */
				/* const arr1 = [211,{idol: 'BLAKCPINK'}]
				const arr2 = JSON.parse(JSON.stringify(arr1))
				arr2[0] = 327
				arr2[1].idol = '朴彩英'
				console.log(arr1, '原数据')
				console.log(arr2, '深拷贝并修改') */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值