I want to create an object from a de-serialized property

Asked 1 years ago, Updated 1 years ago, 61 views

I am writing a web application that communicates with the server using JSON in Typescript.When serializing/decisualizing JSON, JSON does not include methods, so I thought of creating objects using decisualized data, but I don't know how to do it.

Now I'm writing the following code.

class Pen{
    constructor(public color:String, public size:number){}
    draw(): void {
        // do something
    }
}
varjson=JSON.stringify(new Pen("rgb(0,0,0)"), 10);
varpen_data=<Pen>JSON.parse(json);
// pen_data.draw(); // TypeError: pen_data.draw is not a function

I want to create Pen objects from //pen_data
var new_pen = new Pen(pen_data.color,pen_data.size);

However, this code needs to be rewritten one by one when Pen's properties increase, and if you want to do the same in other classes, you have to write a similar code.

How do I write this code generic?

javascript json typescript

2022-09-30 17:58

1 Answers

I don't think there's a direct way.While object-oriented "objects" deal with data and operations in a lump, serialization stores or restores only the "data" part of an object, and in principle, object-oriented "objects" are incompatible with data perpetuation.

There are several possible solutions.

This is the sample code method presented by the questioner.Handle Pen objects and corresponding JSON format data completely separately.You have to call the constructor one by one during the de-serialization, and each time the properties increase or decrease, the de-serialization part is modified.Anyway, it's tedious and tedious, and the presence of Pen objects and their corresponding JSON data makes the data structures redundant, but object-oriented programming is in a sense a "right" way.

You give up using the class and define draw as an independent function, not a Pen class method. Pen becomes an interface, not a class, and the substance of the pen is just an object without a method.

 function draw (pen:Pen) {
    ....
}

interface Pen { 
    color:String; 
    size:Number; 
}

var blackPen: Pen = { color: "rgb(0,0,0)", size:10};

draw (blackPen);

varjson=JSON.stringify (blackPen);
varpen=<Pen>JSON.parse(json);

draw(pen);

I think it's a simple and easy-to-understand method, and it also has the advantage of being able to serialize/decrystallize at once, even if the data structure becomes more complex.For example,

interface PaintTool{
    penList—Pen;
    canvasWidth: Number;
    canvasHeight:Number;
    filePath:String;
}

Even larger data structures, such as the Pen inside, can be serialized/decerialized in one go if an object does not have a method inside.However, the disadvantage is that it rarely uses object-oriented programming-like features such as classes and prototypes; it cannot be used when Pen has subclasses and draw is overridden.

You can use a library like resurrect-js.There are some limitations, not all objects can be serialized, and I haven't checked if it's available for TypeScript classes, but I think it's probably similar to what the questioner imagined.

According to Readme, resurrect-js can write as follows:

functionFoo(){}
Foo.prototype.greet=function() {return "hello";};

// Behavior is reserved:
varnecromancer = new Resurrect();
varjson=necromancer.stringify(new Foo());
var foo=necromancer.resurrect(json);
foo.greet();//=> "hello"

It is also intuitive to use the Resurrect#stringify method instead of JSON.parse and Resurrect#resurrect instead of JSON.parse.The method seems to be conditionally serializable.It depends on the purpose, but it's worth considering.

JavaScript provides a highly flexible method of meta-programming, which allows you to interact directly with __proto__, or dynamically examine the names of properties held by objects in Object.keys properties.https://stackoverflow.com/questions/3871731/dynamic-object-construction-in-javascript">dynamic object construction in javascript?).

Java and others have the ability to use reflection to perform such serialization.To make objects serializable in Java, you need to define constructors with no arguments because they are dynamically de-serialized in that way.That's how we do it with the correct-js mentioned in 3.However, it is not always possible to use such methods for your own use, for example, because the questioner uses TypeScript, it is not always possible to divert the resurrect-js made for JavaScript.If you can't use a library like resurrect-js, you can implement a similar mechanism for your own use.

Using metaprogramming to implement such a mechanism independently, it may not be impossible to automatically serialize/decrystallize properties as they increase or decrease, but such metaprogramming is not a complex, bug-prone and easy way to handle.Static typing of TypeScript is also not helpful.It's not easy at all, so you should think that meta-programming is the last resort.

I would choose 2.I think it's the simplest and easiest way to understand if you're not obsessed with object-oriented programming.I don't feel uncomfortable because I can't use object-oriented classes or prototypes in this situation.I think this serialization problem is an easy-to-understand example of the disadvantages of object-oriented programming that lumps data and operations together.The problem was solved naturally by trying to perpetuate or restore persistent data such as color and size.


2022-09-30 17:58

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.