我知道JSON.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();
答案 0 :(得分:4)
问题在于这一行:
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 }) ...
。)
答案 1 :(得分:1)
如何将数据与功能分开?
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);
}
}
答案 2 :(得分:1)
取代:
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
调用正确设置的,所以方法可行。