文章列表

深拷贝 & 浅拷贝

Champ2026.04.29 13:58访问量0 次阅读
深拷贝 & 浅拷贝

拷贝的内容

  • 浅拷贝只拷贝第一层数据,对于值类型,拷贝值,对于引用类型,拷贝引用,因此修改浅拷贝的对象会意外修改原对象
  • 深拷贝递归复制所有层级的数据。原对象和拷贝对象完全独立。

浅拷贝的实现方式

//浅拷贝的实现方式
//1.展开运算符
const original = { a: 1, b: { c: 2 },c:null,d:undefined };
const shallowCopy = { ...original };

shallowCopy.a = 100;          // 修改基本类型,不影响原对象
shallowCopy.b.c = 200;        // 修改深层对象,会影响原对象

console.log(original.b.c);    // 200 (被改变了)
console.log(original.c);      // null
console.log(original.d);      // undefined

//2.Object.assign()
const original = { a: 1, b: { c: 2 },c:null,d:undefined };
const shallowCopy = Object.assign({}, original);

shallowCopy.b.c = 200;
console.log(original.b.c);    // 200
console.log(original.c);      // null
console.log(original.d);      // undefined

//3.数组操作(slice(),concat(),Array.from())
const original = [1, { x: 10 }];
const shallowCopy = original.slice();   // 或者 [...original]

shallowCopy[1].x = 999;
console.log(original[1].x);   // 999

//4.手动循环实现
function shallowCopy(obj) {
  const result = {};
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {//只保留自身属性(不要父类上的)
      result[key] = obj[key];
    }
  }
  return result;
}

深拷贝的实现方式

//1.Json.parse(Json.stringify(obj))
//局限性:1.无法复制特殊类型(Nah,undefined,Function,Symbol,regexp,Date,Map,
//Set,Infinity)2.无法处理循环引用(报错)
const original = {
  a: 1,
  b: { c: 2 },
  d: [3, 4]
};

console.log(original);
console.log(JSON.stringify(original));
const deepCopy = JSON.parse(JSON.stringify(original));
console.log(deepCopy.b.c); //2

deepCopy.b.c = 200;
deepCopy.d[0] = 999;
console.log(deepCopy.b.c); //200

console.log(original.b.c);   // 2 (未改变)
console.log(original.d[0]);  // 3 (未改变)

//2.structuredClone()
const original = {
  a: 1,
  b: { c: 2 },
  d: new Date(),
  e: /regex/,
  f: new Map([['key', 'value']])
};

const deepCopy = structuredClone(original);

console.log(deepCopy.d === original.d);   // false (日期对象被复制)
console.log(deepCopy.f === original.f);   // false (Map 被复制)
// 支持循环引用
original.self = original;
const copy2 = structuredClone(original);  // 不会报错

//3.手动递归实现
function deepClone(obj, hash = new WeakMap()) {
  // 处理 null 或非对象
  if (obj === null || typeof obj !== 'object') return obj;
  
  // 处理循环引用
  if (hash.has(obj)) return hash.get(obj);
  
  // 处理日期、正则等特殊对象
  if (obj instanceof Date) return new Date(obj);
  if (obj instanceof RegExp) return new RegExp(obj);
  if (obj instanceof Map) {
    const mapCopy = new Map();
    hash.set(obj, mapCopy);
    for (let [k, v] of obj) {
      mapCopy.set(deepClone(k, hash), deepClone(v, hash));
    }
    return mapCopy;
  }
  if (obj instanceof Set) {
    const setCopy = new Set();
    hash.set(obj, setCopy);
    for (let v of obj) {
      setCopy.add(deepClone(v, hash));
    }
    return setCopy;
  }
  
  // 处理数组和普通对象
  const cloneObj = Array.isArray(obj) ? [] : {};
  hash.set(obj, cloneObj);
  
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      cloneObj[key] = deepClone(obj[key], hash);
    }
  }
  return cloneObj;
}
历史留言 (0)
ICP备案号浙ICP备2026065730号-1公安备案号浙公网安备33019202003213号