关键词:
【中文标题】将 ES6 类对象序列化为 JSON【英文标题】:Serializing an ES6 class object as JSON 【发布时间】:2017-03-05 05:41:52 【问题描述】:class MyClass
constructor()
this.foo = 3
var myClass = new MyClass()
我想将myClass
对象序列化为 json。
我能想到的一种简单方法是,因为每个成员实际上都是 javascript 对象(数组等)。我想我可以维护一个变量来保存成员变量。
this.prop.foo = this.foo
等等。
我希望为类对象找到一个 toJSON/fromJSON
库,因为我将它们与其他语言(如 swift/java)一起使用,但找不到用于 javascript 的库。
也许类结构太新,或者我的要求可以在没有库的情况下以某种方式轻松实现。
【问题讨论】:
你听说过JSON.stringify()
吗?这符合你的要求吗?
您有这样做的理由吗?
@Pineda 是的,我想将可序列化的数据存储在 react redux 存储中。但是,答案似乎表明我可以将我的类对象存储在 redux 中,因为它已经是可序列化的。
相关:反序列化:***.com/questions/38922990/…
【参考方案1】:
与您想在 JS 中字符串化的任何其他对象一样,您可以使用JSON.stringify
:
JSON.stringify(yourObject);
class MyClass
constructor()
this.foo = 3
var myClass = new MyClass()
console.log(JSON.stringify(myClass));
另外值得注意的是,您可以自定义stringify
如何序列化您的对象,方法是给它一个toJSON
method。用于在结果 JSON 字符串中表示您的对象的值将是对该对象调用 toJSON
方法的结果。
【讨论】:
如何反序列化它。 @IWuZuoJSON.parse( string )
谢谢。 JSON.parse(string) 返回一个 json 对象。不是 MyClass 的实例。
@IWuZhuo 为此,我建议您在类上创建一个静态方法,该方法接受该对象并通过创建具有 JSON 中属性的对象来返回该类的实例。开箱即用的 Javascript 无法做到这一点,但我会说自己编写很容易
要反序列化,它并不是那么简单,尤其是在涉及复杂的嵌套对象时,但是有一个轻量级库可以做到这一点。详情请查看我的回答。【参考方案2】:
我知道这个问题已经很老了,但我一直在睁大眼睛,直到我写了一个紧凑的、真实的、“安全的”解决方案。
反序列化返回仍然具有附加工作方法的对象。
您唯一需要做的就是在序列化器的构造函数中注册要使用的类。
class Serializer
constructor(types)this.types = types;
serialize(object)
let idx = this.types.findIndex((e)=> return e.name == object.constructor.name);
if (idx == -1) throw "type '" + object.constructor.name + "' not initialized";
return JSON.stringify([idx, Object.entries(object)]);
deserialize(jstring)
let array = JSON.parse(jstring);
let object = new this.types[array[0]]();
array[1].map(e=>object[e[0]] = e[1];);
return object;
class MyClass
constructor(foo) this.foo = foo;
getFoo()return this.foo;
var serializer = new Serializer([MyClass]);
console.log(serializer.serialize(new MyClass(42)));
//[0,[["foo",42]]]
console.log(serializer.deserialize('[0,[["foo",42]]]').getFoo());
//42
以上内容应该足以让您继续前进,但可以找到更多详细信息和缩小版here。
【讨论】:
此示例不处理递归对象初始化。如果类Person
包含成员Address
,反序列化后你将无法调用Address
的方法。【参考方案3】:
我遇到过这个库,它可以对复杂对象(包括嵌套对象和数组)进行序列化和反序列化:
https://github.com/typestack/class-transformer
它至少有两种方法:
plainToClass() -> json obj to class
classToPlain() -> class to json obj
【讨论】:
【参考方案4】:我制作了一个模块esserializer 来解决这个问题。它是一个序列化 JavaScript 类实例的实用程序,并将“序列化文本”反序列化为实例对象,并保留所有类/属性/方法等。
要序列化一个实例,只需调用serialize()
方法:
const ESSerializer = require('esserializer');
let serializedString = ESSerializer.serialize(anObject);
serialize()
的内部机制是:将实例的属性及其类名信息递归保存到字符串中。
要从字符串反序列化,只需调用deserialize()
方法,将所有涉及的类作为参数传递:
const ESSerializer = require('esserializer');
const ClassA = require('./ClassA');
const ClassB = require('./ClassB');
const ClassC = require('./ClassC');
let deserializedObj = ESSerializer.deserialize(serializedString, [ClassA, ClassB, ClassC]);
deserialize()
的内部机制是:手动组合对象及其原型信息,递归。
【讨论】:
replit.com/@deanc1/SickOblongMicroinstruction#index.js 这适用于一级深层嵌套对象 - 谢谢@shaochuancs【参考方案5】:如果您不介意将类定义传递给解码,这很容易。
// the code
const encode = (object) => JSON.stringify(Object.entries(object))
const decode = (string, T) =>
const object = new T()
JSON.parse(string).map(([key, value]) => (object[key] = value))
return object
// test the code
class A
constructor(n)
this.n = n
inc(n)
this.n += n
const a = new A(1)
const encoded = encode(a)
const decoded = decode(encoded, A)
decoded.inc(2)
console.log(decoded)
【讨论】:
如果您不使用嵌套对象,这是一个很好的解决方案。但是,当您尝试这样做时,您会看到失败:replit.com/@deanc1/PerfumedBustlingAngle#index.js【参考方案6】:不是一个新话题,但有一个新的解决方案:现代方法(2021 年 12 月)是使用 @badcafe/jsonizer
: https://badcafe.github.io/jsonizer
在展示一个类的例子之前,让我们从一个简单的数据结构开始:
const person =
name: 'Bob',
birthDate: new Date('1998-10-21'),
hobbies: [
hobby: 'programming',
startDate: new Date('2021-01-01'),
,
hobby: 'cooking',
startDate: new Date('2020-12-31'),
,
]
const personJson = JSON.stringify(person);
//
// "name": "Bob",
// "birthDate": "1998-10-21T00:00:00.000Z",
// "hobbies": [
//
// "hobby": "programming",
// "startDate": "2021-01-01T00:00:00.000Z"
// ,
//
// "hobby": "cooking",
// "startDate": "2020-12-31T00:00:00.000Z"
//
// ]
//
// store or send the data
请注意,日期被序列化为字符串,如果您解析该 JSON,日期将不会是 Date
实例,它们将是 String
s
现在,让我们使用 Jsonizer ?
// in Jsonizer, a reviver is made of field mappers :
const personReviver = Jsonizer.reviver<typeof person>(
birthDate: Date,
hobbies:
'*':
startDate: Date
);
const personFromJson = JSON.parse(personJson, personReviver);
JSON 文本中的每个日期字符串都已映射到解析结果中的 Date
对象。
Jsonizer 可以用递归嵌套的自定义类、第三方类、内置类或子 JSON 结构(数组、对象)无差别地恢复 JSON 数据结构(数组、对象)或类实例。
现在,让我们改用一个类:
// in Jsonizer, a class reviver is made of field mappers + an instance builder :
@Reviver<Person>( // ? bind the reviver to the class
'.': (name, birthDate, hobbies) => new Person(name, birthDate, hobbies), // ? instance builder
birthDate: Date,
hobbies:
'*':
startDate: Date
)
class Person
constructor( // all fields are passed as arguments to the constructor
public name: string,
public birthDate: Date
public hobbies: Hobby[]
)
interface Hobby
hobby: string,
startDate: Date
const person = new Person(
'Bob',
new Date('1998-10-21'),
[
hobby: 'programming',
startDate: new Date('2021-01-01'),
,
hobby: 'cooking',
startDate: new Date('2020-12-31'),
,
]
);
const personJson = JSON.stringify(person);
const personReviver = Reviver.get(Person); // ? extract the reviver from the class
const personFromJson = JSON.parse(personJson, personReviver);
最后,让我们使用 2 个类:
@Reviver<Hobby>(
'.': (hobby, startDate) => new Hobby(hobby, startDate), // ? instance builder
startDate: Date
)
class Hobby
constructor (
public hobby: string,
public startDate: Date
)
@Reviver<Person>(
'.': (name, birthDate, hobbies) => new Person(name, birthDate, hobbies), // ? instance builder
birthDate: Date,
hobbies:
'*': Hobby // ? we can refer a class decorated with @Reviver
)
class Person
constructor(
public name: string,
public birthDate: Date,
public hobbies: Hobby[]
)
const person = new Person(
'Bob',
new Date('1998-10-21'),
[
new Hobby('programming', new Date('2021-01-01')),
new Hobby('cooking', new Date('2020-12-31')
]
);
const personJson = JSON.stringify(person);
const personReviver = Reviver.get(Person); // ? extract the reviver from the class
const personFromJson = JSON.parse(personJson, personReviver);
【讨论】:
【参考方案7】:您需要能够递归地重新初始化对象。有一个无参数的构造函数不是必须的,你可以不用它。
这是我执行深层复制的方式:
class Serializer
constructor(types)
this.types = types;
markRecursive(object)
// anoint each object with a type index
let idx = this.types.findIndex(t =>
return t.name === object.constructor.name;
);
if (idx !== -1)
object['typeIndex'] = idx;
for (let key in object)
if (object.hasOwnProperty(key) && object[key] != null)
this.markRecursive(object[key]);
cleanUp(object)
if (object.hasOwnProperty('typeIndex'))
delete object.typeIndex;
for (let key in object)
if (object.hasOwnProperty(key) && object[key] != null)
console.log(key);
this.cleanUp(object[key]);
reconstructRecursive(object)
if (object.hasOwnProperty('typeIndex'))
let type = this.types[object.typeIndex];
let obj = new type();
for (let key in object)
if (object.hasOwnProperty(key) && object[key] != null)
obj[key] = this.reconstructRecursive(object[key]);
delete obj.typeIndex;
return obj;
return object;
clone(object)
this.markRecursive(object);
let copy = JSON.parse(JSON.stringify(object));
this.cleanUp(object);
return this.reconstructRecursive(copy);
这个想法很简单:在序列化时,每个已知 类型(this.types
中的类型)的成员都被一个名为typeIndex
的成员涂抹。反序列化后,我们递归地初始化每个有typeIndex
的子结构,然后去掉它以避免污染结构。
【讨论】:
javascriptserializer类对象序列化为json,json反序列化为对象
...Web服务器之间传递的数据。说白了就是能够直接将一个C#对象传送到前台页面成为javascript对象。要添加System.Web.Extensions.dll的引用。该类位于System.Web.Script.Serialization命名空间下。一、属性MaxJsonLength获取或设置JavaSc 查看详情
Android:无法使用 Gson 将 json 反序列化为类对象
】Android:无法使用Gson将json反序列化为类对象【英文标题】:Android:CannotdeserializejsonintoclassobjectwithGson【发布时间】:2021-12-0304:41:46【问题描述】:给定下一个json:"alpha_two_code":"AR","web_pages":["http://www.atlantida.edu.ar/"],"name":"Universida... 查看详情
将 JSON 反序列化为对象
】将JSON反序列化为对象【英文标题】:DeserializingJSONintoanobject【发布时间】:2016-03-1707:26:47【问题描述】:我有一些JSON:"foo":["bar":"baz","bar":"qux"]我想将其反序列化为一个集合。我已经定义了这个类:publicclassFoopublicstringbarget;set;... 查看详情
将 JSON 反序列化为对象
】将JSON反序列化为对象【英文标题】:DeserializingJSONintoanobject【发布时间】:2021-12-1621:52:42【问题描述】:我有一些JSON:"foo":["bar":"baz","bar":"qux"]我想将其反序列化为一个集合。我已经定义了这个类:publicclassFoopublicstringbarget;set;... 查看详情
如何将具有不同值的相同 JSON 对象反序列化为 java 类
】如何将具有不同值的相同JSON对象反序列化为java类【英文标题】:HowdeserializethesameJSONobjectbutwithdiferentvaluesintoajavaclass【发布时间】:2019-12-2906:40:33【问题描述】:我有以下情况:有时我会得到这个JSON对象"id":1,"cp":"male","money":10.... 查看详情
JSON将Scala案例类序列化为仅字符串和整数
...和整数。意思是,如果有嵌套类型,它会被序列化为JSON对象的字符串化版本,而不是JSON对象。例子:caseclassDeepest(someNum:Int)caseclassIn 查看详情
如何将具有嵌套属性的 JSON 对象反序列化为 Symfony 实体?
】如何将具有嵌套属性的JSON对象反序列化为Symfony实体?【英文标题】:HowdoIdeserializeaJSONobject-whichhasanestedproperty-toaSymfonyentity?【发布时间】:2021-09-2123:14:45【问题描述】:我正在将JSON反序列化为一个php类(一个Symfony实体),它... 查看详情
将 JSON 反序列化为现有对象 (Java)
】将JSON反序列化为现有对象(Java)【英文标题】:DeserializeJSONintoexistingobject(Java)【发布时间】:2012-09-1304:09:20【问题描述】:我想知道如何让JacksonJSON库将JSON反序列化为现有对象?我试图找到如何做到这一点;但它似乎只能接受... 查看详情
无法使用 Jackson ObjectMapper 将 Json 序列化为 Java 对象
】无法使用JacksonObjectMapper将Json序列化为Java对象【英文标题】:Can\'tserializeJsontoJavaobjectusingJacksonObjectMapper【发布时间】:2019-08-2123:12:30【问题描述】:我正在编写一个可以导出/导入数据的Javaspringbootmvc应用程序。我写了一个包... 查看详情
使用 Jackson 将通用 java 对象序列化为 JSON
】使用Jackson将通用java对象序列化为JSON【英文标题】:SerializinggenericjavaobjecttoJSONusingJackson【发布时间】:2011-12-2317:37:50【问题描述】:当我尝试将以下类实例转换为JSON(使用Jackson)时publicclassRPCRespond<Result>privateintcode;private... 查看详情
Newton JSON 如何将对象序列化为空括号?
】NewtonJSON如何将对象序列化为空括号?【英文标题】:NewtonJSONHowtoserializeobjecttoemptybrackets?【发布时间】:2021-11-1622:03:42【问题描述】:我有一个通用的对象类publicclassMyClass[Required]publicstringTitleget;set;[Required]publicintOrderIndexget;set;... 查看详情
将json字符串反序列化为python中的对象
】将json字符串反序列化为python中的对象【英文标题】:Deserializeajsonstringtoanobjectinpython【发布时间】:2013-03-0619:10:21【问题描述】:我有以下字符串"action":"print","method":"onData","data":"MadanMohan"我想反序列化为类的对象classpayloadstringa... 查看详情
无法将 JSON 数组反序列化为 C# 对象 [关闭]
】无法将JSON数组反序列化为C#对象[关闭]【英文标题】:UnableDeserializeJSONArraytoC#object[closed]【发布时间】:2021-09-2812:24:24【问题描述】:我有一个HTML页面和一些进行AJAX调用的Javascript代码。在我的API(C#)的服务器端,我收到一个JSON... 查看详情
Python将类序列化为JSON [重复]
...:2017-01-2014:34:32【问题描述】:我有一个要构建大量JSON对象的需求。并且有许多不同的定义,理想情况下我想像类一样管理它们并构造对象并按需将它们转储到JSON。是否有现成的包装/食谱让我可以执行以下操作为了简单起见,... 查看详情
将Json字符串反序列化为对象java
】将Json字符串反序列化为对象java【英文标题】:DeserializeJsonstringtoobjectjava【发布时间】:2020-02-0312:15:20【问题描述】:我得到了正确的字符串形式的响应。但是当我尝试将它建模到我的模型类时,我无法获得这些值。我猜我没... 查看详情
将objective-c自定义对象序列化为OSX的JSON?
】将objective-c自定义对象序列化为OSX的JSON?【英文标题】:serializeobjective-ccustomobjecttoJSONforOSX?【发布时间】:2012-10-0921:37:33【问题描述】:我是Mac开发的新手,在寻找好的资源时遇到了一些麻烦。我当前的问题是自定义objective-c... 查看详情
Symfony SerializerInterface 将 json 反序列化为类不起作用
...来很容易,但由于某种原因不能按预期工作。属性之一是对象数组,当反序 查看详情
轻松将对象序列化为 JSON
】轻松将对象序列化为JSON【英文标题】:EasilyserializeanobjecttoJSON【发布时间】:2015-01-1913:31:12【问题描述】:如何将Swift对象序列化为JSON,例如以下对象:classOrdervarid:Intvartitle:Stringvaremail:Stringinit(id:Int,title:String,email:String)self.id=i... 查看详情