深浅拷贝

84 阅读1分钟

数据的类型分基本类型和引用类型两种

  • 基本类型:undefined,null,Boolean,String,Number,Symbo
  • 引用类型:Object,Array,Date,Function,RegExp等

浅拷贝

创建一个新的对象,拷贝值(如果属性是基本数据类型,拷贝的就是基本数据类型的值,如果数据是引用数据类型,拷贝的是引用类型的内存地址)浅拷贝如果碰到的是引用数据类型,那么拷贝前和拷贝后是互相影响的

const person2 = {
	name:'乔丹'
}
// 实现一个浅拷贝
function shallowClone(source){
	// 创建一个新对象
	let newObj = {}
	// 循环 source
	for (let i in source) {
		// for in 会遍历原型链上的属性
		// 通过 hasOwnProperty 来判断,source对象上是否有这个属性
		if (source.hasOwnProperty(i)) {
			newObj[i] = source[i]
		}
	}
	return newObj
}
const person3 = shallowClone(person)
person3.name = '科比'
console.log(person2.name)
console.log(person3.name)

深拷贝

深拷贝是从内存中完整的拷贝一份出来,在堆内存中开一个新的内存空间,与原对象完全独立。修改新对象不会影响原对象,如果属性是引用数据类型,那么就会开辟一个新的空间

<!-- JSON 转换 -->
JSON.parse(JSON.stringify(obj))
<!-- 递归函数 -->
export function deepClone(target) {
  if (typeof target !== 'object' || target === null) {
    return target;
  }
  let dist;
  if (target instanceof Array) {
    // 拷贝数组
    dist = [];
  } else if (target instanceof Function) {
    // 拷贝函数
    dist = (...args) => {
      return target.call(this, args);
    };
  } else if (target instanceof RegExp) {
    // 拷贝正则表达式
    dist = new RegExp(target.source, target.flags);
  } else if (target instanceof Date) {
    // 拷贝日期
    dist = new Date(target);
  } else {
    // 拷贝普通对象
    dist = {};
  }
  for (const key in target) {
    // 过滤掉原型身上的属性
    if (target.hasOwnProperty(key)) {
      // 调用递归函数
      dist[key] = deepClone(target[key]);
    }
  }
  return dist;
}