序列化一个javascript类对象?

时间:2018-07-22 01:59:49

标签: javascript json object serialization

要求很简单。这是一堂课...

class myobj {

    constructor(var1, var2) {
        this.var1 = var1;
        this.var2 = var2;
    }

    addThemUp() {
        return this.var1 + this.var2;
    }

}

现在我做其中之一...

var myInstance = new MyObj(3, 7);

可爱。但是现在我需要对其进行序列化,以便我可以保存它并在以后加载它。像...

serialise(myInstance);
// Save to a file
// ... do some other stuff ...
// load from file
myInstance = unserialise(fileData);
// - or - 
unserialise(fileData, myInstace);
// etc...

如何?我不在乎表示形式采用什么形式,因为它将由同一页面加载。如果仅保存值,则将其加载回对象的一般方法会很好,因为同一页面上有类“模板”来查找函数的定义。

该对象很大并且在变化,因此从JSON复制值以保留功能实际上是无法维护的。但是,可以使用任意数量和类型的变量执行此操作的解决方案将很有用。

即使在现代浏览器中,我也必须坚持使用香草的单文件javascript。

TL; DR:如何在不丢失功能的情况下序列化和反序列化对象?

6 个答案:

答案 0 :(得分:2)

您可以使用document.getElementById("inputTextId").value = "Some string inserted by user"; var textEvent = document.createEvent('TextEvent'); textEvent.initTextEvent('textInput', true, true, null, String.fromCharCode(13), 9, "en-US"); document.getElementById("inputTextId").dispatchEvent(textEvent); ,但要注意,它仅序列化属性,而不序列化方法。因此,要反序列化一个对象,只需创建一个虚拟实例并使用JSON.stringify来使用检索到的对象来更新属性:

Object.assign

示例:

function serialize(instance) {
    var str = JSON.stringify(instance);
    // save str or whatever
}

function unserialize(str, theClass) {
    var instance = new theClass();                  // NOTE: if your constructor checks for unpassed arguments, then just pass dummy ones to prevent throwing an error
    var serializedObject = JSON.parse(str);
    Object.assign(instance, serializedObject);
    return instance;
}

答案 1 :(得分:0)

无法序列化函数。

可以将构造函数设置为始终使用一个对象,并使用Object.assign()将所有输入分配给实例

将可枚举的属性字符串化为json,然后在需要时再次解析json,然后再次将存储的对象传递给new MyObj

class MyObj {

  constructor(obj) {
    const defaults = {var1: 10,var2: 10};
    Object.assign(this, obj || defaults);
  }

  addThemUp() {
    return this.var1 + this.var2 + (this.var3 || 0) + (this.var4 || 0);
  }

  addSomeProps() {
    if (!this.var3 && !this.var4) {
      this.var3 = 10;
      this.var4 = 10
    }
  }

  serialize() {
    return JSON.stringify(this)
  }

}

const myInstance = new MyObj();
console.log('myInstance before more props added', myInstance)
myInstance.addSomeProps()
///stringify the instance object
const json = myInstance.serialize();
// same variables needed to pass to constructor
const storedObj = JSON.parse(json)
// create new instance
const instance2 = new MyObj(storedObj);

console.log('instance 2', instance2)
// try out the methods 
console.log('add in instance 2:', instance2.addThemUp())

答案 2 :(得分:0)

您可以使用JSON.stringify(myInstance); (以序列化对象),然后使用JSON.parse(mymyInstance)将其作为对象取回

答案 3 :(得分:0)

当您以JSON形式序列化对象时,您的类信息将丢失。 为了防止这种情况的发生,您必须手动添加属性以保留原始的类信息。像班名一样 然后,您可以在反序列化时使用该信息位,并将所有信息还原到原始类对象。 这是将JSON返回其原始类对象的一种通用方法:

class Foo{
    constructor(var1, var2){
        // save your class name as property
        this.classname = this.constructor.name;

        this.var1 = var1;
        this.var2 = var2;
    }

    hoo(var3, var4){
        this.var3 = var3;
        this.var4 = var4;
    }

    serialize(){
        return JSON.stringify(this);
    }
}

let foo = new Foo(1, 2);
foo.hoo(3, 4);

//Now we have JSON string:
//'{"classname":"Foo","var1":1,"var2":2,"var3":3,"var4":4}'
let json = foo.serialize();

function deserialize(json){
    //o is [Object object], but it contains every state of the original object
    let o = JSON.parse(json);
    //Get original class instance
    let original_class = eval(o.classname);

    //Create new object of the original class, then restore back property values
    //NOTE: You may not need to pass any parameter to the constructor, since
    //every state of the original object will be restored from o.
    return Object.assign(new original_class(), o);
}

let _foo = deserialize(json);
console.log(_foo instanceof Foo); // returns true;

我还创建了一个small module,它可以与Node.js一起使用并处理嵌套对象,因此,如果您有兴趣,也请检查代码。

答案 4 :(得分:0)

我制作了一个名为 esserializer 的 npm 模块来解决这个问题:在序列化期间保存 JavaScript 类对象值,然后递归反序列化对象实例,保留所有类型/函数信息。

在您的情况下,代码将非常简单:

var ESSerializer = require('esserializer');
var MyObj = require('MyObj');

var myInstance = new MyObj(3, 7);
var serializedText = ESSerializer.serialize(myInstance);
//...do something, or send the above serializedText to another JavaScript environment.
var deserializedObj = ESSerializer.deserialize(serializedText, [MyObj]);

deserializedObj 是一个 MyObj 实例,其中包含所有值/函数/超类信息。

这个模块是一个开源项目。如果您有兴趣,可以查看 GitHub repo 并了解它是如何工作的。

答案 5 :(得分:0)

这个问题的回答有点生硬,...

但有效:)

使用 TypeScript -> https://github.com/typestack/class-transformer