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

如何在JavaScript父类中实现可继承的类实例半深复制方法?

JavaScript类继承中实现通用半深复制方法

要实现父类定义copy方法,所有子类继承后能返回自身类型的实例,同时完成“半深复制”(创建新实例+浅复制属性),可以通过以下方式实现:

核心思路

利用实例的this.constructor属性动态获取当前调用者的构造函数(父类或子类),创建对应类型的新实例后,将原实例的属性浅复制到新实例上。

完整代码实现

class Parent {
  constructor(data) {
    this.data = data;
    this.commonProperty = "parent-shared";
  }

  copy() {
    // 获取当前实例的构造函数(可能是Parent/Child1/Child2)
    const CurrentConstructor = this.constructor;
    // 创建对应类型的新实例
    const copyInstance = new CurrentConstructor();
    // 浅复制原实例的所有可枚举自有属性到新实例
    Object.assign(copyInstance, this);
    return copyInstance;
  }
}

// 子类示例
class Child1 extends Parent {
  constructor(data) {
    super(data);
    this.child1Property = "child1-unique";
  }
}

class Child2 extends Parent {
  constructor(data) {
    super(data);
    this.child2Property = "child2-unique";
  }
}

测试验证

// 测试父类复制
const parent = new Parent([1, 2, 3]);
const parentCopy = parent.copy();
console.log(parentCopy instanceof Parent); // 输出: true
console.log(parentCopy.data === parent.data); // 输出: true(属性浅复制,引用类型共享引用)
console.log(parentCopy.commonProperty === parent.commonProperty); // 输出: true

// 测试Child1复制
const child1 = new Child1([4, 5, 6]);
const child1Copy = child1.copy();
console.log(child1Copy instanceof Child1); // 输出: true
console.log(child1Copy.child1Property); // 输出: "child1-unique"

// 测试Child2复制
const child2 = new Child2([7, 8, 9]);
const child2Copy = child2.copy();
console.log(child2Copy instanceof Child2); // 输出: true
console.log(child2Copy.child2Property); // 输出: "child2-unique"

扩展说明

1. 复制不可枚举属性

如果需要复制实例的不可枚举自有属性,可以替换Object.assign为Object.getOwnPropertyDescriptors和Object.defineProperties:

copy() {
  const CurrentConstructor = this.constructor;
  const copyInstance = new CurrentConstructor();
  // 获取原实例的所有自有属性描述符(包括不可枚举)
  const propDescriptors = Object.getOwnPropertyDescriptors(this);
  // 将属性描述符应用到新实例
  Object.defineProperties(copyInstance, propDescriptors);
  return copyInstance;
}

2. 构造函数需必填参数的场景

如果类的构造函数要求必须传入参数,直接new CurrentConstructor()会导致实例初始化异常。这种情况下可以在构造函数中保存参数,复制时传递:

class Parent {
  constructor(data) {
    // 保存构造参数到实例
    this._constructorArgs = [data];
    this.data = data;
  }

  copy() {
    const CurrentConstructor = this.constructor;
    // 传递保存的构造参数创建实例
    return new CurrentConstructor(...this._constructorArgs);
  }
}

这种方式需要所有子类遵循“保存构造参数到_constructorArgs”的约定,确保复制时能正确初始化实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 02:50:32