You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaScript/TypeScript中复制类实例且保留方法?

解决类实例复制保留方法的问题

首先明确原因:JSON.parse(JSON.stringify(inst1))只会序列化对象的可枚举自有属性,类的方法大多定义在原型链上,不会被JSON序列化,所以复制出来的只是普通Object,不是类的实例,自然调用不了原型上的方法。

以下是几种无需逐个复制属性的可行方案:

1. 浅拷贝:Object.assign + 新实例

如果实例属性都是基本类型(无嵌套引用类型),这种方式最简便:

// 假设你的类是MyClass
const inst2 = new MyClass();
Object.assign(inst2, inst1);

Object.assign会把inst1的所有可枚举自有属性拷贝到inst2上,而inst2是类的实例,原型链完整,方法全部保留。缺点是如果属性是引用类型(如对象、数组),两个实例会共享同一引用,修改inst2的嵌套属性会影响inst1。

2. 自定义深拷贝函数(保留实例原型)

如果需要完全独立的深拷贝(嵌套属性也互不影响),可以写一个专门处理类实例的深拷贝函数:

function deepCopyInstance(obj) {
  // 非对象直接返回
  if (obj === null || typeof obj !== 'object') return obj;
  
  // 判断是否为类实例(而非普通Object)
  if (obj.constructor !== Object) {
    const newInstance = new obj.constructor();
    // 遍历并递归拷贝所有自有属性
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        newInstance[key] = deepCopyInstance(obj[key]);
      }
    }
    return newInstance;
  }
  
  // 普通对象/数组的深拷贝逻辑
  const newObj = Array.isArray(obj) ? [] : {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = deepCopyInstance(obj[key]);
    }
  }
  return newObj;
}

// 使用方式
const inst2 = deepCopyInstance(inst1);

这个函数会识别类实例,创建对应类的新实例后递归拷贝所有属性,既保留了原型方法,又实现了完全独立的深拷贝。

3. 结合类构造函数的属性初始化(如果支持)

如果你的类构造函数本来就支持传入属性对象初始化,可以配合扩展运算符使用:

// 假设MyClass的构造函数支持接收属性参数
class MyClass {
  constructor(props) {
    Object.assign(this, props);
  }
  method1() { /* 方法逻辑 */ }
}

// 复制实例
const inst2 = new MyClass({ ...inst1 });

这种方式简洁高效,前提是类的构造函数已经做了属性初始化的处理。


内容的提问来源于stack exchange,提问作者George Keeling

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 02:15:34