【问题标题】:Cyclic Object Exception on JSON.stringify when with RxJs Subject in a class在类中使用 RxJs 主题时 JSON.stringify 上的循环对象异常
【发布时间】:2025-12-02 18:25:01
【问题描述】:

我在使用序列化恰好具有 Rxjs 主题的类时遇到循环对象异常错误。如果我在课堂上订阅该主题,当我尝试字符串化时,我会得到一个循环对象异常。我的示例类这个...

export class ThingToStringIfy
{
  private someProp : string;
  private aSubject = new Subject();

   constructor() {
     this.aSubject.subscribe();
}

}

所以我的问题是我是否以某种方式错误地使用了该主题,或者我是否碰巧发现了一个错误。我目前正计划使用 JSON 替换函数或类似 circle-json-es6 的东西。任何有关解决方法或改进的建议将不胜感激。如果它是一个错误,我想成为一个好公民并实际报告它。

谢谢

这里是违规代码的链接: https://stackblitz.com/edit/angular-cpfsuu?embed=1&file=app/hello.component.ts

【问题讨论】:

  • 你要字符串化什么?你为什么要把它串起来?
  • 这里有一篇类似的文章考虑了 observables 的序列化:*.com/questions/34794995/…

标签: json angular typescript rxjs


【解决方案1】:

一般来说,observables 和 private 成员都不应该被序列化。这会导致序列化对象被不应该存在的属性污染。

一种方法是在 JS 输出中隐藏(不可枚举)私有 TypeScript 属性。这可以通过装饰器来实现:

function Private() {
  return function (target: any, prop: string, descriptor?: PropertyDescriptor) {
    if (descriptor) {
      // method
      descriptor.enumerable = false;
    } else {
      // property initializer
      let propSymbol = Symbol(prop);

      Object.defineProperty(target, prop, {
        configurable: true,
        enumerable: false,
        get() { return this[propSymbol] },
        set(value) { this[propSymbol] = value }
      });
    }
  };
}

export class ThingToStringIfy {
  @Private() private someProp : string;
  @Private() private aSubject = new Subject();
  ...
}

装饰器将private 属性排除在JSON.stringify 和其他只需要拥有可枚举属性的地方。

另一种方法是实现toJSON method 将被JSON.stringify 使用而不是默认例程:

export class ThingToStringIfy {
  private someProp : string;
  private aSubject = new Subject();
  ...
  toJSON() {
    const publicThis = Object.assign({}, this);
    // or lodash.omit or any alternative
    delete publicThis['someProp'];
    delete publicThis['aSubject'];
    return publicThis;
  }
}

【讨论】:

  • 非常好.. 我唯一需要更改的是在 Private 前面添加 @
  • 是的,这是一个错字。很高兴它有帮助。
最近更新 更多