如何在 JavaScript 中序列化对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11759917/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to serialize an object in JavaScript?
提问by Bdfy
For example I have class:
例如我有课:
function Test() {
}
Test.prototype = {
'setTest' : function(test) {
this.test = test;
}
}
var test = new Test();
Test.setTest('test');
I want to save object test in database. How to serialize object test to string? (methods, variables, etc)
我想在数据库中保存对象测试。如何将对象测试序列化为字符串?(方法、变量等)
回答by Roest
Simple with json
简单的json
JSON.stringify( test );
回答by jcolebrand
In this case, for the question you're asking, there really isn't a way to do what you want. The problem with your request lies in "serializing everything attached to the object, including functions".
在这种情况下,对于您提出的问题,确实没有办法做您想做的事。您的请求的问题在于“序列化附加到对象的所有内容,包括函数”。
Serialization normally only occurs for data, because executables are usually machine bound, in that they are compiled for a given machine, based on certain characteristics. Now, it's reasonable to say that javascript functions just require a javascript interpreter, because javascript is write-once, run-everywhere. But when people write serializers, because all serializers tend to work the same, we write them for data only. In this case, the industry standard is JSON, which is an object-data only serializer.
序列化通常只发生在数据上,因为可执行文件通常是机器绑定的,因为它们是基于特定特征为给定机器编译的。现在,可以合理地说 javascript 函数只需要一个 javascript 解释器,因为 javascript 是一次编写,到处运行。但是当人们编写序列化程序时,因为所有序列化程序的工作方式都相同,所以我们只为数据编写它们。在这种情况下,行业标准是 JSON,它是仅对象数据的序列化程序。
There are three solutions that avail themselves to you at this point:
在这一点上,有三种解决方案可供您使用:
- Write your own serialier/deserializer that encapsulates functions. This can be tricky, because not all javascript engines will give you access to the source.
- Write your own re-loading mechanism that generates a specific new initialized type on each restore, and save the typename as one of the properties on serialization. That way the initialization of each variable gives you the methods, and then merging with the data gives you the complete object.
- Store each function as a string and eval it on the fly as you need it. This is incredibly tricky, and is quite prone to errors. I can think of no case where this becomes helpful, because it's quite fragile. However, it is an option, and cannot be overlooked.
- 编写您自己的用于封装函数的串行器/解串器。这可能很棘手,因为并非所有 javascript 引擎都会让您访问源代码。
- 编写您自己的重新加载机制,在每次恢复时生成特定的新初始化类型,并将类型名保存为序列化的属性之一。这样,每个变量的初始化为您提供方法,然后与数据合并为您提供完整的对象。
- 将每个函数存储为一个字符串,并根据需要动态地对其进行评估。这非常棘手,而且很容易出错。我想不出这会有什么帮助,因为它非常脆弱。然而,它是一种选择,不容忽视。
I know that 3 is a sub-answer for 1, so you can consider it that there are only two useful answers.
我知道 3 是 1 的子答案,因此您可以认为只有两个有用的答案。
I know that superficially this works on Chrome and IE9, so it should work everywhere the majority of users are likely to use it:
我知道从表面上看这适用于 Chrome 和 IE9,所以它应该适用于大多数用户可能使用它的任何地方:
var abc = function(thing) { return thing; }
abc.toString();
// gives "function(thing) { return thing; }" on the command line
So you can certainly serialize the methods as strings in place of the actual method, but you're going to need to create a duplicate object so you can capture every element on the source object (I think, rather than replacing them in place).
因此,您当然可以将方法序列化为字符串代替实际方法,但是您将需要创建一个重复的对象,以便您可以捕获源对象上的每个元素(我认为,而不是将它们替换到位)。
Hopefully this helps you think about the problem some more, and maybe to realize you don't need to serialize the methods (nobody ever does that I know of, not reasonably).
希望这可以帮助您更多地思考问题,并且可能会意识到您不需要序列化方法(据我所知,没有人这样做,这不合理)。
回答by Tim
The best way to do this is to write your own serialize method which creates a JSON object with attributes, based on your getters. Normally you define a getter per attribute. So it should work for most cases (so you don't have to define a serialize method for each class).
最好的方法是编写您自己的序列化方法,该方法基于您的 getter 创建一个带有属性的 JSON 对象。通常,您为每个属性定义一个 getter。所以它应该适用于大多数情况(所以你不必为每个类定义一个序列化方法)。
function serialize(obj) {
var serialized = {};
for(var prop in obj) {
if (obj.hasOwnProperty(prop) && typeof obj[prop] == 'function') {
if (/^get.*/.test(prop)) {
var value = obj[prop]();
var name = prop.replace('get', '');
if (typeof value === 'object') {
serialized[name] = this.serialize(value);
continue;
}
serialized[name] = value;
}
}
}
return serialized;
};
To reset your attribute values back to the class you have two options:
要将属性值重置回类,您有两个选择:
- Create a function in your class which creates a valid object instance based on the serialized JSON.
- Create a unserialize method and map the JSON with your class using the setters.
- 在您的类中创建一个函数,该函数基于序列化的 JSON 创建一个有效的对象实例。
- 创建一个反序列化方法并使用 setter 将 JSON 映射到您的类。
Example:
例子:
function unserialize(obj, emptyClass) {
// Check emptyClass for setters and map the data from obj to it.
return 'class instance';
}
回答by Matt Ball
回答by jbabey
I've had to support functionality similar to this before. I ended up saving the name of the function as a string and serializing it as JSON. Then when I come back to the client, I execute the function using a helper like the one posted in this question.
我以前不得不支持与此类似的功能。我最终将函数的名称保存为字符串并将其序列化为 JSON。然后当我回到客户端时,我使用一个像这个问题中发布的助手一样的助手来执行该函数。
If anyone has a better way to solve this problem, I'd want to see it!
如果有人有更好的方法来解决这个问题,我想看看!
回答by Yegor Zaremba
In Node.jssince version 8.x you can use v8
module, documentation
在Node.js 中,从 8.x 版开始,您可以使用v8
模块、文档
const v8 = require('v8')
const dataToTransfer = v8.serialize(test)
// result: <Buffer ff 0d 6f 22 04 74 65 73 74 22 04 74 65 73 74 7b 01>
const initialData = v8.deserialize(dataToTransfer)
// result: { test: 'test' }
But if you work in the browser, you can serialize an object to a JSON stringby calling the function JSON.stringify()
documentation
但是,如果您在浏览器中工作,则可以通过调用函数文档将对象序列化为JSON 字符串。JSON.stringify()
回答by Biso
I recently had to find a solution for this problem. I'm sure it can be improved upon.
我最近不得不为这个问题找到解决方案。我相信它可以改进。
First I created a module for instantiating the "serialisable" object.
首先,我创建了一个用于实例化“可序列化”对象的模块。
function MyObj(serialised){
this.val = "";
if(serialised){
var unserialised = JSON.parse(serialised);
for (var i in unserialised) {
this[i] = unserialised[i];
}
}
}
MyObj.prototype.myMethod = function () { return this.val;};
module.exports = MyObj;
you of course have to consider error handling and other validations.
您当然必须考虑错误处理和其他验证。