【问题标题】:typescript JSON.stringify loose type and functiontypescript JSON.stringify 松散类型和函数
【发布时间】:2016-05-01 15:39:41
【问题描述】:

我知道 JSON.stringify 没有 stringify 函数,但是好的做法是什么,因为水合作用真的很累。我不想创建一个新对象。有什么想法吗?

class pers {
    name = "";
    last = "";

    constructor(name: string, last: string) {
        this.name = name;
        this.last = last;
    }

    alo() {
        alert(this.name);
    }
}

let pa = new pers("ben", "troq");
let s = JSON.stringify(pa);
let o = <pers>JSON.parse(s);
let pb = new pers("", "");

pb = o;
pb.alo();

【问题讨论】:

  • 不相关,但请帮自己一个忙,让代码保持一致(在 = 周围放置空格,或者如果这让你更快乐,则不要在任何地方使用)并写下名称(person 类,与属性 firstnamelastname 例如,而不是 pers、name、last)。 pasopb 代表什么?

标签: json typescript


【解决方案1】:

问题出在这一行:

let o = <pers>JSON.parse(s);

我相信你认为这是一个类型转换,但它不是。这是一个type-assertion,并不意味着运行时支持。基本上,您只是告诉编译器相信 o 的类型是 pers,但在 运行时 并非如此:

o instanceof pers; // false

您需要手动创建对象实例,使用您的 JSON 作为 Nitzan suggests,或者创建一个读取一些元数据信息的例程,以自动创建具有相应属性的正确实例。


对于后一种方法,我建议尝试TypedJSON,我创建它是为了针对这个确切的问题提供一种优雅且适应性广泛的解决方案:

@JsonObject
class pers {
    @JsonMember name = "";
    @JsonMember last = "";

    constructor(name?: string, last?: string) {
        this.name = name;
        this.last = last;
    }

    alo() {
        alert(this.name);
    }
}
let o = TypedJSON.parse(s, pers);
o instanceof pers; // true
o.alo(); // "ben"

注意无参数构造函数,这是必需的(在大多数类似的系统中也是如此)。

此解决方案基于ReflectDecorators,但不是必需的(但是,如果没有它,您将需要手动指定属性的构造函数:例如@JsonMember({ type: String }) ...)。

【讨论】:

    【解决方案2】:

    如何将数据与功能分开?

    interface PersData {
        name: string;
        last: string;
    }
    
    class pers {
        private data: PersData;
    
        constructor(data: PersData | string) {
            this.data = typeof data === "string" ? JSON.parse(data) : data;
        }
    
        alo() {
            alert(this.data.name);
        }
    }
    

    【讨论】:

      【解决方案3】:

      替换:

      let o  = <pers>JSON.parse(s);
      let pb = new pers("", "");
      
      pb = o;
      pb.alo();
      

      与:

      let o  = JSON.parse(s);
      let pb = Object.create(pers.prototype);
      Object.assign(pb, o);
      
      pb.alo();
      

      它应该工作。 Object.create (ES5.1) 创建一个对象,其链接原型是来自 pers 类的对象,但不运行 pers 构造函数。然后Object.assign (ES6) 将属性从 JSON 未序列化的对象复制到 pb 引用的对象。因为Object.create 正确设置了原型,所以调用方法将起作用。

      【讨论】:

      • 你能解释一下你的答案,而不是在这里放代码吗?使您的答案有效的关键是什么?我问是因为通过解释,其他人可以从您的答案中学习并将其应用于其他问题。这就是 stackoverflow 的意义 --- 不要盲目地复制和粘贴一些代码。
      • 对不起,我以为 sn-p 是不言而喻的。编辑并添加了解释。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-04
      • 2020-11-10
      • 2019-03-31
      • 1970-01-01
      • 1970-01-01
      • 2019-06-06
      • 2018-09-15
      相关资源
      最近更新 更多