JSON 至 Javascript Class

JSON to Javascript Class

我有一个从 nosql 数据库获取此 Json 对象的 http 请求:

let jsonBody = {
    birthday : 1997,
    firstname: 'foo',
    lastname:'bar'
}

然后我想将此信息加载到 Student 模型中:

class Student{
    constructor(){

    }

    getFullname(){
        return this.lastname+' '+this.firstname
    }
    getApproxAge(){
        return 2018- this.birthday
    }
}

通常,我会把这个方法加到这个class:

fromJson(json){
    this.studentId = json.studentId;
    this.birthday = json.birthday;
    this.firstname = json.firstname;
    this.lastname = json.lastname;
}

我会按如下方式使用它:

let student = new Student()
student.fromJson(jsonBody)
console.log(student.getFullname())
console.log(student.getApproxAge())

这很好用,但我的问题是我有:现实中的 100 个礼节。我是否必须在 fromJson 方法中将所有属性一一写入?

另外,如果专有名称发生了变化,比方说:姓氏变成了姓氏,我必须修改它吗?

有没有一种更简单的方法可以动态地将这些值分配给对象 student 但保留其所有方法?

像这样:

fromJson(json){
    this = Object.assign(this, json) //THIS IS NOT WORKING
}

只需分配给一个实例:

 static from(json){
   return Object.assign(new Student(), json);
 }

所以你可以这样做:

 const student = Student.from({ name: "whatever" });

或者让它成为一个实例方法并放弃赋值:

 applyData(json) {
   Object.assign(this, json);
 }

所以你可以:

 const student = new Student;
 student.applyData({ name: "whatever" });

它也可以是构造函数的一部分:

 constructor(options = {}) {
  Object.assign(this, options);
 }

那么你可以这样做:

 const student = new Student({ name: "whatever" });

And also, if a property name has changed, let's say: lastname became LastName, I will have to fix it?

是的,你必须解决这个问题。

javascript 中无法将 json 反序列化为 类。所以我写了一个库 ts-serializable 来解决这个问题。

import { jsonProperty, Serializable } from "ts-serializable";

export class User extends Serializable {

    @jsonProperty(String)
    public firstName: string = ''; // default value necessarily

    @jsonProperty(String, void 0)
    public lastName?: string = void 0; // default value necessarily

    @jsonProperty(Date)
    public birthdate: Date = new Date(); // default value necessarily

    public getFullName(): string {
        return [
            this.firstName,
            this.lastName
        ].join(' ');
    }

    public getAge(): number {
        return new Date().getFullYear() - this.birthdate.getFullYear();
    }
}

const user: User = new User().fromJSON(json);
user.getFullName(); // work fine and return string
user.getAge(); // work fine and return number

// or
const user: User = User.fromJSON(json);
user.getFullName(); // work fine and return string
user.getAge(); // work fine and return number

该库还在反序列化期间检查类型。