Top*_*era 53 javascript serialization
我的应用程序中有很多JavaScript对象,例如:
function Person(age) {
this.age = age;
this.isOld = function (){
return this.age > 60;
}
}
// before serialize, ok
var p1 = new Person(77);
alert("Is old: " + p1.isOld());
// after, got error Object #<Object> has no method 'isOld'
var serialize = JSON.stringify(p1);
var _p1 = JSON.parse(serialize);
alert("Is old: " + _p1.isOld());
Run Code Online (Sandbox Code Playgroud)
请参阅JS Fiddle.
我的问题是:是否有一个最佳实践/模式/提示来恢复序列化之前的相同类型的对象(在这种情况下类Person的实例)?
我的要求:
Fel*_*ing 58
JSON没有数据类型的功能.您只能序列化字符串,数字,对象,数组和布尔值(和null
)
您可以创建自己的toJson
方法,只传递真正必须序列化的数据:
Person.prototype.toJson = function() {
return JSON.stringify({age: this.age});
};
Run Code Online (Sandbox Code Playgroud)
类似于反序列化:
Person.fromJson = function(json) {
var data = JSON.parse(json); // Parsing the json string.
return new Person(data.age);
};
Run Code Online (Sandbox Code Playgroud)
用法是:
var serialize = p1.toJson();
var _p1 = Person.fromJson(serialize);
alert("Is old: " + _p1.isOld());
Run Code Online (Sandbox Code Playgroud)
为了减少工作量,您可以考虑将每个需要序列化的所有数据存储在每个Person
实例的特殊"数据"属性中.例如:
function Person(age) {
this.data = {
age: age
};
this.isOld = function (){
return this.data.age > 60 ? true : false;
}
}
Run Code Online (Sandbox Code Playgroud)
然后序列化和反序列化只是调用JSON.stringify(this.data)
和设置实例的数据instance.data = JSON.parse(json)
.
这将保持toJson
和fromJson
方法简单,但你必须调整你的其他功能.
边注:
您应该将该isOld
方法添加到函数的原型中:
Person.prototype.isOld = function() {}
Run Code Online (Sandbox Code Playgroud)
否则,每个实例都有自己的该函数实例,这也会增加内存.
我写了serialijse,因为我遇到了和你一样的问题.
你可以在https://github.com/erossignon/serialijse找到它
它可以在nodejs或浏览器中使用,并且可以用于将一组复杂的对象从一个上下文(nodejs)序列化和反序列化到另一个上下文(浏览器),反之亦然.
var s = require("serialijse");
var assert = require("assert");
// testing serialization of a simple javascript object with date
function testing_javascript_serialization_object_with_date() {
var o = {
date: new Date(),
name: "foo"
};
console.log(o.name, o.date.toISOString());
// JSON will fail as JSON doesn't preserve dates
try {
var jstr = JSON.stringify(o);
var jo = JSON.parse(jstr);
console.log(jo.name, jo.date.toISOString());
} catch (err) {
console.log(" JSON has failed to preserve Date during stringify/parse ");
console.log(" and has generated the following error message", err.message);
}
console.log("");
var str = s.serialize(o);
var so = s.deserialize(str);
console.log(" However Serialijse knows how to preserve date during serialization/deserialization :");
console.log(so.name, so.date.toISOString());
console.log("");
}
testing_javascript_serialization_object_with_date();
// serializing a instance of a class
function testing_javascript_serialization_instance_of_a_class() {
function Person() {
this.firstName = "Joe";
this.lastName = "Doe";
this.age = 42;
}
Person.prototype.fullName = function () {
return this.firstName + " " + this.lastName;
};
// testing serialization using JSON.stringify/JSON.parse
var o = new Person();
console.log(o.fullName(), " age=", o.age);
try {
var jstr = JSON.stringify(o);
var jo = JSON.parse(jstr);
console.log(jo.fullName(), " age=", jo.age);
} catch (err) {
console.log(" JSON has failed to preserve the object class ");
console.log(" and has generated the following error message", err.message);
}
console.log("");
// now testing serialization using serialijse serialize/deserialize
s.declarePersistable(Person);
var str = s.serialize(o);
var so = s.deserialize(str);
console.log(" However Serialijse knows how to preserve object classes serialization/deserialization :");
console.log(so.fullName(), " age=", so.age);
}
testing_javascript_serialization_instance_of_a_class();
// serializing an object with cyclic dependencies
function testing_javascript_serialization_objects_with_cyclic_dependencies() {
var Mary = { name: "Mary", friends: [] };
var Bob = { name: "Bob", friends: [] };
Mary.friends.push(Bob);
Bob.friends.push(Mary);
var group = [ Mary, Bob];
console.log(group);
// testing serialization using JSON.stringify/JSON.parse
try {
var jstr = JSON.stringify(group);
var jo = JSON.parse(jstr);
console.log(jo);
} catch (err) {
console.log(" JSON has failed to manage object with cyclic deps");
console.log(" and has generated the following error message", err.message);
}
// now testing serialization using serialijse serialize/deserialize
var str = s.serialize(group);
var so = s.deserialize(str);
console.log(" However Serialijse knows to manage object with cyclic deps !");
console.log(so);
assert(so[0].friends[0] == so[1]); // Mary's friend is Bob
}
testing_javascript_serialization_objects_with_cyclic_dependencies();
Run Code Online (Sandbox Code Playgroud)
我是https://github.com/joonhocho/seri的作者。
Seri 是 JSON + 自定义(嵌套)类支持。
您只需要提供toJSON
并fromJSON
序列化和反序列化任何类实例。
这是一个嵌套类对象的示例:
import seri from 'seri';
class Item {
static fromJSON = (name) => new Item(name)
constructor(name) {
this.name = name;
}
toJSON() {
return this.name;
}
}
class Bag {
static fromJSON = (itemsJson) => new Bag(seri.parse(itemsJson))
constructor(items) {
this.items = items;
}
toJSON() {
return seri.stringify(this.items);
}
}
// register classes
seri.addClass(Item);
seri.addClass(Bag);
const bag = new Bag([
new Item('apple'),
new Item('orange'),
]);
const bagClone = seri.parse(seri.stringify(bag));
// validate
bagClone instanceof Bag;
bagClone.items[0] instanceof Item;
bagClone.items[0].name === 'apple';
bagClone.items[1] instanceof Item;
bagClone.items[1].name === 'orange';
Run Code Online (Sandbox Code Playgroud)
希望它有助于解决您的问题。