# 10-深拷贝和浅拷贝

深拷贝和浅拷贝都只针对引用数据类型,浅拷贝会对对象逐个成员依次拷贝,但只复制内存地址,而不复制对象本身,新旧对象成员还是共享同一内存;深拷贝会另外创建一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

  • 区别:浅拷贝只复制对象的第一层属性,而深拷贝会对对象的属性进行递归复制。

# 浅拷贝实现

// 浅拷贝
let clone = function(obj){
	if (typeof obj != "object") {
		return obj;
	}
	if (Array.isArray(obj)) {
		return obj.slice();
	}
	let newObj = {};
	for(let key in obj){
		newObj[key] = obj[key];
	}
	return newObj;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

JavaScript中,存在浅拷贝的现象有:

  • Object.assign
  • Array.prototype.slice(), Array.prototype.concat()
  • 使用拓展运算符实现的复制
// es6语法糖,实现浅拷贝
// 语法 返回值为目标对象
Object.assign(target, ...sources);

const arr = ["One", "Two", "Three"]
const newArr = arr.slice(0)
const newArr = arr.concat()
const newArr =  [...arr]
1
2
3
4
5
6
7
8

# 深拷贝实现

常见的深拷贝方式有:

  • _.cloneDeep()
  • jQuery.extend()
  • JSON.stringify()
  • 手写循环递归
// 手写循环递归,简易版
let deepClone = function(obj){
	if (typeof obj !== "object") {
		return obj;
	}
	let newObj = Array.isArray(obj) ? [] : {};

	for(let key in obj){
		if (typeof obj[key] !== "object") {
			newObj[key] = obj[key];
		} else {
			newObj[key] = deepClone(obj[key]);
		}
	}
	return newObj;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

深拷贝参考文献 (opens new window)