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

JavaScript中如何更优地克隆通过new创建的对象?

嘿,我完全理解你那种“这方法能用但总觉得不够优雅”的感受——克隆new出来的对象确实有更规范、更灵活的方案,分不同场景给你梳理下:

克隆通过new创建的对象的更好方法

首先得明确:克隆分浅克隆和深克隆,不同需求对应不同方案,先从最常用的场景说起:

1. 浅克隆(适合无嵌套引用类型的对象)

如果你的对象只有字符串、数字、布尔这类基本类型属性,这两种方法简洁又高效:

扩展运算符(ES6+首选)

直接展开原对象的所有可枚举属性到新对象,写法超清爽:

const original = new YourCustomClass();
const clone = { ...original };

⚠️ 注意:这种方式会生成一个普通Object实例,而非原类的实例。如果不需要保留原类的方法/原型链,这完全够用。

Object.assign()

和扩展运算符效果一致,兼容性稍好(适合老项目):

const original = new YourCustomClass();
const clone = Object.assign({}, original);

2. 保留原类实例的克隆(需要继承原类方法)

如果克隆后的对象必须是原构造函数的实例(比如要调用原类的原型方法),可以这样做:

构造函数 + Object.assign

先创建一个原类的空实例,再把原对象的属性拷贝进去,既保留实例身份又完成克隆:

const original = new YourCustomClass();
const clone = new YourCustomClass();
Object.assign(clone, original);

如果原类的构造函数需要参数,你可以传入原对象的对应参数,或者先创建空实例再覆盖属性。

原型继承 + 属性拷贝

如果原类的构造函数有复杂初始化逻辑,不想重复执行,可以用Object.create继承原型,再拷贝属性:

const original = new YourCustomClass();
// 继承原对象的原型链
const clone = Object.create(Object.getPrototypeOf(original));
// 拷贝所有可枚举属性
Object.assign(clone, original);

3. 深克隆(处理嵌套引用类型)

如果对象里有嵌套的对象、数组这类引用类型,浅克隆只会拷贝引用(修改克隆对象的嵌套属性会影响原对象),这时候需要深克隆:

原生structuredClone(现代环境首选)

浏览器和Node.js都支持的原生API,能处理大部分类型(包括Date、RegExp、Map、Set等),用法简单:

const original = new YourCustomClass({ nested: { name: "test" } });
const clone = structuredClone(original);

⚠️ 限制:无法克隆函数、Symbol、DOM节点这类不可序列化的对象,遇到这些会报错。

手动递归克隆(自定义场景)

如果需要处理不可序列化的属性,或者要自定义克隆规则(比如跳过某些属性),可以写一个递归函数:

function deepClone(obj) {
  // 基本类型直接返回
  if (obj === null || typeof obj !== 'object') return obj;
  
  // 处理数组
  if (obj instanceof Array) {
    return obj.map(item => deepClone(item));
  }
  
  // 处理自定义类实例
  if (obj.constructor !== Object) {
    const cloneInstance = new obj.constructor();
    // 拷贝自身属性
    Object.assign(cloneInstance, obj);
    // 递归克隆嵌套属性
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        cloneInstance[key] = deepClone(obj[key]);
      }
    }
    return cloneInstance;
  }
  
  // 处理普通对象
  const plainClone = {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      plainClone[key] = deepClone(obj[key]);
    }
  }
  return plainClone;
}

// 使用示例
const original = new YourCustomClass({ nested: { age: 20 } });
const clone = deepClone(original);

总结一下

  • 浅克隆+不需要原类实例:用扩展运算符或Object.assign
  • 浅克隆+需要原类实例:构造函数+Object.assign或Object.create方案
  • 深克隆:优先用structuredClone,有特殊需求则手动递归

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:36:46