js object 深、浅拷贝

基本类型值

  • 常见基本数据类型:string、number、boolean、undefined、null、symbol;
  • 基本类型是按值来访问的,从一个变量复制基本类型到另一个变量后,这两个变量是完全独立的,二者互不影响。
var str = "zlq":
var str2 = str;
str2 = "qlz";
console.log(str);   //zlq

引用类型值

  • 常见引用类型:Object、Array、Function、Math、Date等;
  • 引用类型值时引用类型的实例,是保存在堆内存中的一个对象。同样和基本类型值一样会将变量的值复制到新变量上,不同的是对于变量的值,它是一个指针,指向存储在堆内存中的对象。
var obj1 = {'name': 'zlq'};
var obj2 = obj1;
obj2.name = 'qlz';
console.log(obj1); // {'name': 'qlz'}
console.log(obj2); // {'name': 'qlz'}

浅拷贝: 如果属性是基本类型,拷贝的就是基本类型的值;如果属性是引用类型,拷贝的就是内存地址;所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
常见方法:Object.assign(target, …sources);扩展运算符

注意:
Object.assign、… 均为第一层深拷贝,第二层起为浅拷贝;
拷贝后与拷贝前的第二层对象或数组仍然是引用的同一个地址。

深拷贝: 是指完全复制一个新的对象出来,它们在堆内存中完全占据两个不同的内存地址。
常见方法:JSON.parse(JSON.stringify());cloneDeep();

function deepClone(source) {
	var temp = source.constructor === Array ? [] : {};   // 初始化
	for(var keys in source) {
		if(source.hasOwnProperty(keys)) {
			if(source[keys] && typeof(source[keys]) === 'object') {  // 判断是否是引用类型
				temp[keys] = source[keys].constructor === Array ? [] : {};
				temp[keys] = deepClone(source[keys]);
			} else {  // 基本类型直接赋值、Function也会赋值
				temp[keys] = source[keys];
			}
		}
	}
	return temp;
}

JSON.stringify() 拷贝时注意事项:

  1. 如果有函数、undefined、symbo,经过 JSON.stringify() 处理后 JSON 字符串中的键值对会消失;
  2. 无法拷贝不可枚举的属性,无法拷贝对象的原型链;、
  3. 拷贝Date引用类型,会变成字符串

总结:

  • 实际开发中,并不需要拷贝很多特殊的引用类型,深拷贝直接使用 JSON.parse(JSON.stringify()) 即可。
  • 一个完整的拷贝,需要考虑很多边界条件。因此在开发中,建议使用第三方库,如 merge 等。
发布了115 篇原创文章 · 获赞 49 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/zlq_CSDN/article/details/104616245