???深拷贝和浅拷贝

JS对象的深拷贝和浅拷贝有什么区别?
	◇ 对象B复制对象A,当改变B的时候,A跟着变,那么就是浅拷贝,如果A不变,两者相互不影响,那么就是深拷贝。

⑵ 数据类型:
	◇ 值类型(Stack): 包括 Number, String, Boolean, Null, Undefined, Symbol(ES6),
					    拷贝操作均属于深拷贝,因为它们操作的是实际值。
	◇ 引用类型(Heap):包括 Array, Object, Function 等对象,拷贝操作可以是浅拷贝,也可以是深拷贝。	

⑴ 值类型拷贝都是深拷贝(number, string, boolean, null, undefined, symbol)let a = "hello";
	let b = a;
	b = "world";
	console.log(a);
	
	// hello


⑵ 引用类型 array 浅拷贝

	let arrA = [1, 2, 3, 4, 5];
	let arrB = arrA;
	arrB.push(6);
	console.log(arrA);
	
	// [1, 2, 3, 4, 5, 6]  A 同时发生了变化

⑶ 引用类型 object 浅拷贝

	let objA = { name: "zhangsan", age: 30, course: { chinese: 100 } };
	let objB = objA;
	objB.name = "lisi";
	objB.course.chinese = 89;
	console.log(JSON.stringify(objA));
	
	// {"name":"lisi","age":30,"course":{"chinese":89}}
	缺点:
		会忽略undefined
		会忽略symbol
		会忽略函数
		不能解决循环引用的对象 (会报错)

⑴ 对于单个层级的对象,使用 ES6 语法块 { ... x} 或者 Object.assign() 即可实现深拷贝。
	let objA = { name: "zhangsan", age: 30 };
	let objB = {...objA};
	// let objB = Object.assign({},objA);
	objB.name = "lisi";
	console.log(objA);
	// {name: "zhangsan", age: 30} 

  使用Object.assign解决这个问题。
	let a = {
	  age: 1
	}
	let b = Object.assign({}, a)
	a.age = 2
	console.log(b.age) // 1

	
  对于嵌套对象,使用这两个方法就“歇菜了”
	let objA = { name: "zhangsan", age: 30, course: { chinese: 100 } };
	let objB = {...objA};  // 不好用了吧
	objB.name = "lisi";
	objB.course.chinese = 89;
		// {"name":"zhangsan","age":30,"course":{"chinese":89}}

⑵ 嵌套对象,比较“暴力”的深拷贝方法是使用 JSON.parse(JSON.stringify(objA))let objA = { name: "zhangsan", age: 30, course: { chinese: 100 } };
	let objB = JSON.parse(JSON.stringify(objA));
	
	objB.name = "lisi";
	objB.course.chinese = 89;
	
	// {"name":"zhangsan","age":30,"course":{"chinese":100}}
⑶ 手写DeepClone,利用递归的方式实现对象的层层遍历。下面的代码并不完善,例如没有考虑对 date,file,map, set等对象的拷贝。经典库 loadash 提供了 cloneDeep 来实现深拷贝,阅读其源码,发现对10多种常见的对象做了处理,已经较为完善.
◇ 注意判断值类型和引用类型
◇ 注意判断是数组还是对象
◇ 递归

const obj1 = {
    age: 20,
    name: 'xxx',
    address: {
        city: 'beijing'
    },
    arr: ['a', 'b', 'c']
}

const obj2 = deepClone(obj1)
obj2.address.city = 'shanghai'
obj2.arr[0] = 'a1'
console.log(obj1.address.city)
console.log(obj1.arr[0])

function deepClone(obj = {}) {
    if (typeof obj !== 'object' || obj == null) {
        // obj 是 null ,或者不是对象和数组,直接返回
        return obj
    }
    // 初始化返回结果
    let result
    if (obj instanceof Array) {
        result = []
    } else {
        result = {}
    }
    for (let key in obj) {
        // 保证 key 不是原型的属性
        if (obj.hasOwnProperty(key)) {
            // 递归调用!!!
            result[key] = deepClone(obj[key])
        }
    }
    // 返回结果
    return result
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值