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

如何获取this对象的子类?TypeScript中safeCall方法实现求助

问题解答

一、修复TypeScript中safeCall扩展方法的类型问题

你的safeCall方法主要有两个问题:一是typeof this的写法不符合TypeScript语法规范,二是使用箭头函数会导致this指向错误(箭头函数的this是词法作用域绑定,不会指向调用该方法的对象)。下面是完整的修复方案:

1. 正确定义接口与实现

我们需要利用TypeScript的this类型,让函数参数正确接收当前对象的类型,同时改用普通函数来保留调用时的this上下文:

// 扩展Object接口,添加safeCall方法的类型定义
interface Object {
  safeCall<T>(this: this, func: (obj: this) => T | null | undefined): T | null;
}

// 实现safeCall方法,使用普通函数而非箭头函数
Object.prototype.safeCall = function<T>(func: (obj: typeof this) => T | null | undefined): T | null {
  try {
    const value = func(this);
    // 使用空值合并运算符,统一处理undefined和null的情况
    return value ?? null;
  } catch {
    return null;
  }
};

2. 安全获取measureUnit.id的示例

假设你的fetch请求返回的是Product类型(或包含Product的Promise),可以这样使用safeCall来安全嵌套取值:

interface MeasureUnit {
  id: number;
  title: string;
}

interface Product {
  id: number;
  title: string;
  measureUnit: MeasureUnit | null;
}

// 假设fetch返回Promise<Product>,需先await获取实例
const product = await fetch('....some request').then(res => res.json() as Product);

// 使用safeCall安全获取measureUnit的id
const measureUnitID = product.safeCall(p => p.measureUnit?.id);
// 如果measureUnit为null或访问出错,measureUnitID会是null;否则返回对应的id数值

这里p => p.measureUnit?.id利用可选链操作符?.提前处理measureUnit为null的情况,再结合safeCall捕获可能的异常,实现完全安全的取值。

二、获取当前this对象的子类

在JavaScript/TypeScript中,你可以通过this.constructor来获取当前对象所属的构造函数(如果是子类实例,会直接返回子类构造函数)。

1. 获取直接子类构造函数

class BaseClass {
  getCurrentSubclass() {
    return this.constructor;
  }
}

class SubClass extends BaseClass {}

const subInstance = new SubClass();
console.log(subInstance.getCurrentSubclass() === SubClass); // 输出true

2. 获取继承链上的所有子类

如果你需要遍历整个继承链获取所有父类/子类,可以通过Object.getPrototypeOf来实现:

function getAllInheritanceChain(obj: any): Function[] {
  const chain = [];
  let currentConstructor = obj.constructor;
  
  // 遍历直到顶层Object构造函数
  while (currentConstructor !== Object) {
    chain.push(currentConstructor);
    // 获取当前构造函数的原型的原型对应的构造函数
    currentConstructor = Object.getPrototypeOf(currentConstructor.prototype).constructor;
  }
  
  return chain;
}

// 测试
class Grandparent {}
class Parent extends Grandparent {}
class Child extends Parent {}

const child = new Child();
console.log(getAllInheritanceChain(child)); // [Child, Parent, Grandparent]

需要注意的是,如果构造函数的prototype被手动修改过,这个方法可能会出现偏差,不过在常规的继承场景下是可靠的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:32:40