栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何使用JSON对象初始化TypeScript对象

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何使用JSON对象初始化TypeScript对象

这些是一些快速快照,它们显示了几种不同的方式。它们绝不是“完整的”,作为免责声明,我认为这样做不是一个好主意。代码也不是很干净,因为我只是很快地将它们键入在一起。

还要注意:可反序列化的类当然需要具有默认的构造函数,就像我知道任何反序列化的所有其他语言一样。当然,如果您调用不带参数的非默认构造函数,则Javascript不会抱怨,但是该类最好为此做准备(此外,它并不是真正的“打字方法”)。

选项#1:完全没有运行时信息

这种方法的问题主要是,任何成员的名称都必须与其类匹配。这会自动将您限制为每个班级一名相同类型的成员,并破坏了一些良好实践的规则。我强烈建议您这样做,但请在此处列出,因为这是我编写此答案时的第一个“草稿”(这也是为什么名称为“
Foo”等的原因)。

module Environment {    export class Sub {        id: number;    }    export class Foo {        baz: number;        Sub: Sub;    }}function deserialize(json, environment, clazz) {    var instance = new clazz();    for(var prop in json) {        if(!json.hasOwnProperty(prop)) { continue;        }        if(typeof json[prop] === 'object') { instance[prop] = deserialize(json[prop], environment, environment[prop]);        } else { instance[prop] = json[prop];        }    }    return instance;}var json = {    baz: 42,    Sub: {        id: 1337    }};var instance = deserialize(json, Environment, Environment.Foo);console.log(instance);

选项2: name 属性

为了摆脱选项#1中的问题,我们需要某种有关JSON对象中节点类型的信息。问题在于,在Typescript中,这些都是编译时构造,我们在运行时需要它们-
但是运行时对象只是在设置它们之前才意识到它们的属性。

一种方法是让类知道其名称。不过,您也需要在JSON中使用此属性。实际上,您 需要在json中使用它:

module Environment {    export class Member {        private __name__ = "Member";        id: number;    }    export class ExampleClass {        private __name__ = "ExampleClass";        mainId: number;        firstMember: Member;        secondMember: Member;    }}function deserialize(json, environment) {    var instance = new environment[json.__name__]();    for(var prop in json) {        if(!json.hasOwnProperty(prop)) { continue;        }        if(typeof json[prop] === 'object') { instance[prop] = deserialize(json[prop], environment);        } else { instance[prop] = json[prop];        }    }    return instance;}var json = {    __name__: "ExampleClass",    mainId: 42,    firstMember: {        __name__: "Member",        id: 1337    },    secondMember: {        __name__: "Member",        id: -1    }};var instance = deserialize(json, Environment);console.log(instance);

选项3:明确说明成员类型

如上所述,类成员的类型信息在运行时不可用-除非我们使它可用。我们只需要对非原始成员执行此操作,我们很好:

interface Deserializable {    getTypes(): Object;}class Member implements Deserializable {    id: number;    getTypes() {        // since the only member, id, is primitive, we don't need to        // return anything here        return {};    }}class ExampleClass implements Deserializable {    mainId: number;    firstMember: Member;    secondMember: Member;    getTypes() {        return { // this is the duplication so that we have // run-time type information :/ firstMember: Member, secondMember: Member        };    }}function deserialize(json, clazz) {    var instance = new clazz(),        types = instance.getTypes();    for(var prop in json) {        if(!json.hasOwnProperty(prop)) { continue;        }        if(typeof json[prop] === 'object') { instance[prop] = deserialize(json[prop], types[prop]);        } else { instance[prop] = json[prop];        }    }    return instance;}var json = {    mainId: 42,    firstMember: {        id: 1337    },    secondMember: {        id: -1    }};var instance = deserialize(json, ExampleClass);console.log(instance);

选项4:详细但整洁的方式

__2016年1月3日 更新:
正如@GameAlchemist在注释想法,实现中指出的那样,从Typescript
1.7开始,可以使用类/属性装饰器以更好的方式编写以下描述的解决方案。

序列化总是一个问题,我认为最好的方法就是最短的方法。在所有选项中,这是我想要的,因为该类的作者完全控制了反序列化对象的状态。如果我不得不猜测,我会说所有其他选择迟早都会给您带来麻烦(除非Javascript提出了一种本机处理方式)。

的确,以下示例并未体现灵活性。它确实确实只是复制了类的结构。不过,您必须在这里记住的区别是,该类具有完全控制权,可以使用它想要控制整个类的状态的任何JSON(您可以计算事物等)。

interface Serializable<T> {    deserialize(input: Object): T;}class Member implements Serializable<Member> {    id: number;    deserialize(input) {        this.id = input.id;        return this;    }}class ExampleClass implements Serializable<ExampleClass> {    mainId: number;    firstMember: Member;    secondMember: Member;    deserialize(input) {        this.mainId = input.mainId;        this.firstMember = new Member().deserialize(input.firstMember);        this.secondMember = new Member().deserialize(input.secondMember);        return this;    }}var json = {    mainId: 42,    firstMember: {        id: 1337    },    secondMember: {        id: -1    }};var instance = new ExampleClass().deserialize(json);console.log(instance);


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/370126.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号