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

如何为泛型类型分配原型,解决sessionStorage解析后丢失对象方法的问题

解决方案

核心问题是JSON.parse只会生成无自定义原型的普通对象,且TypeScript泛型仅存在于编译阶段,运行时无法直接获取泛型T的构造函数信息,因此需要显式传入目标类的构造函数作为参数,再做原型绑定或实例初始化。

方案1:手动挂载原型(适合简单类场景)

直接给反序列化得到的普通对象挂载目标类的原型,无需修改原有类定义:

public static getObject<T>(key: string, clazz: new () => T): T | null {
    const storageStr = sessionStorage.getItem(key);
    if (!storageStr) return null;
    const plainObj = JSON.parse(storageStr);
    Object.setPrototypeOf(plainObj, clazz.prototype);
    return plainObj as T;
}

调用示例

假设你有自定义类User,调用时传入构造函数即可:

const user = YourService.getObject('current-user', User);
// 可正常调用User类的原型方法
user?.sayHello();

方案2:构造函数注入数据(适合复杂类场景)

如果你的类包含构造初始化逻辑、私有属性、访问器等,更推荐通过构造函数接收反序列化数据创建实例,完全规避原型修改带来的隐患:

  1. 先在自定义类中支持传入普通对象初始化:
class User {
    name: string;
    id: number;

    constructor(plainObj?: Partial<User>) {
        if (plainObj) {
            Object.assign(this, plainObj);
        }
    }

    // 自定义方法
    getUserIdStr() {
        return `user_${this.id}`;
    }
}
  1. 调整getObject方法,用反序列化数据生成类实例:
public static getObject<T>(key: string, clazz: new (plain: any) => T): T | null {
    const storageStr = sessionStorage.getItem(key);
    if (!storageStr) return null;
    const plainObj = JSON.parse(storageStr);
    return new clazz(plainObj);
}

注意事项

  • JSON序列化会自动丢弃函数、Symbol、undefined、循环引用等类型的值,如果类中包含这类属性,序列化存储前需要做自定义转换,反序列化后再手动恢复。
  • Object.setPrototypeOf存在一定性能损耗,大数据量场景优先选择方案2。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 05:45:01