要求很简单。这是一堂课...
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:如何在不丢失功能的情况下序列化和反序列化对象?
答案 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)